2016-02-28 3 views
0

Я посмотрел forward declaring, чтобы обойти ошибку компиляции «ошибка: переменная или поле« mov_avg »объявлено void».
Следующий сценарий: существует один файл data_proc.cpp с основным(), включающим настраиваемый заголовок my_mov_avg.h, который встраивает функцию mov_avg(shared). Кроме того, функция заголовка обращается к class cl_shared внутри основного файла. Файлы выглядят как:
Вперед декларация класса в заголовке вызывает неполный тип

#include <string.h>  //c++ headers 
#include <iostream> //red? 

#include "my_mov_avg.h" //outsourced function 

using namespace std; 

/* class accessed from header*/ 
class cl_shared { 
public: 
    //constructor 
    cl_shared() { }; 

    int getint() { 
     return a; 
    } 
private: 
    int a; 
}; 
cl_shared shared; //class object 

/*main calling function inside header*/ 
int main(int argc, char **argv){ 
    mov_avg(shared); 
    getchar(); 
    return 0; 
} 

Заголовок my_mov_avg.h файла:

//in .h 
void say(); 
void mov_avg(); 

//in .cpp 
#include <string.h>  
#include <iostream> 
#include "my_mov_avg.h" 


void say() { 
    std::cout << "Ohai from another .cpp file!"; 
} 
class cl_shared; //Forward declaration 
void mov_avg(cl_shared shared){ 
     std::cout<<" int from class: "<< shared.getint()<< std::endl; 
} 

Теперь я жду объявил так, что тип аргумента функции определяется Я получил эту ошибку компиляции:

error: ‘shared’ has incomplete type 
void mov_avg(cl_shared shared){ 
    ^
/my_mov_avg.cpp:9:11: error: forward declaration of ‘class cl_shared’ 
class cl_shared; 
    ^

Как получить его для компиляции и плохой дизайн для доступа к классу cl_shared из заголовка?
Я пытаюсь добиться многократного доступа к данным (здесь разбито на изменение int), откуда была вызвана функция заголовка.
Я мог бы разбить class cl_shared в отдельный файл заголовка и включить его в оба, но я не уверен, кроме того, он вызывает другой файл заголовка (который может и не понадобиться).
EDIT добавлен аргумент внутри my_mov_avg.h
void mov_avg(cl_shared shared);, но до сих пор вызывает:

my_mov_avg.h:3:14: error: variable or field ‘mov_avg’ declared void 
void mov_avg(cl_shared shared); 

Sidenote: быстрый и грязный хак, чтобы сломать один большой CPP-файл, чтобы поместить функцию в отдельный CPP и место #include "seperate.cpp", где первоначально была функция. Используйте только простые программы.

+0

Во-первых, ваше прямое объявление mov_avg() не содержит параметров, как это делает ваше определение. Затем вы не можете перенаправлять классы объявлений и использовать их напрямую, компилятор нуждается в определении в вашем .cpp, поэтому вам нужно поднять определение cl_shared в отдельный заголовок, который использует ваш основной файл и файл my_mov_avg.cpp. – Shaggi

ответ

2

Передовые объявления работают только в том случае, если вы используете класс в качестве указателя/ссылки и не пытаетесь получить доступ к каким-либо его членам. Когда вы передаете по значению, компилятор должен знать точный размер .etc. типа и поэтому нуждается в декларации полного класса.

void mov_avg(cl_shared shared){ 

Здесь вы передаете по значению (то есть вы передаете копию делилась на стеке), поэтому компилятор нуждается в декларации полного класса. Также при доступе к членам класса переключение на проход по указателю/ссылке будет недостаточным, так как компилятору нужно будет знать макет памяти членов класса.

Вам необходимо объявить cl_shared, где-то my_mov_arg.h может получить к нему доступ до его использования.

На стороне, когда вы объявляете неклассические функции-члены в заголовке, например, mov_arg, вы должны объявлять их как встроенные. В противном случае определение функции будет добавлено к каждому исходному файлу, в котором используется заголовок, и вызвать ошибки компиляции.

EDIT. Это должно сделать это. Вы также можете переместить функции-члены из cl_shared.h в файл cl_shared.cpp, если хотите.#pragma раз в верхней части файлов заголовков, чтобы обеспечить заголовок только получает включен один раз в единицу компиляции:

cl_shared.h:

#pragma once 

class cl_shared { 
    public: 
    //constructor 
    cl_shared() { }; 

    int getint() { 
     return a; 
    } 
private: 
    int a; 
}; 

my_mov_avg.h

#pragma once 
#include "cl_shared.h" 

void say(); 
void mov_avg(cl_shared shared); 
+0

Так что мне нужно сделать еще один заголовок, имеющий объявление класса? Также вы предлагаете вывести функцию из заголовка обратно в файл cpp. (Thats, где я начал. Я хочу разбить основной файл) – ItsmeJulian

+0

Если нет необходимости помещать их в отдельные файлы заголовков, вы также можете поместить их в один и тот же заголовочный файл. –

0

Если файл заголовка имеет только

void mov_avg(); 

Тогда это будет другой функции - тот, который не принимает никаких аргументов. C++ сильно набирает функции - перегрузки могут иметь разные сигнатуры аргументов, но одно и то же имя. Таким образом, он видел объявление move_avg(), но не одно из move_avg(cl_shared shared).

Смежные вопросы