2012-06-05 3 views
3

У меня есть заголовочный файл a.h и внутри, что я объявил одну структуру. Название этой структуры: file. Внутри file У меня 3 участников: a, b, c. В a.cpp я реализовал эту структуру и назначил некоторые значения этой структурной переменной.Прямое объявление структуры

Теперь у меня есть другой файл b.h. Внутри я имею переднюю декларацию структуры file. До этого момента, если я скомпилирую, он не покажет ошибку, но когда я собираюсь получить доступ к переменной, присутствующей в этой структуре, через этот класс b.cpp, она выдаст ошибку, например, «undefined struct».

Что я делаю неправильно?

+1

Пожалуйста, перефразируйте вопрос, чтобы использовать заглавные буквы в конце предложения, в противном случае его трудно прочитать. – Naveen

ответ

11

Что является основной причиной ошибки?

Когда вы Форвард объявить тип, компилятор обрабатывает его как неполном типа.

Переднее декларация сообщает компилятору, что существует указанный тип и больше ничего о конкретном type.So, Вы не можете выполнить какие-либо действия (как создание объектов или разыменования указателей к этому типу) на тот тип, который необходим компилятор знать его расположение памяти.

Решение:

Вы не можете объявить вперед, если вам нужно почтительное членов структуры, Вам необходимо включить заголовочный файл в исходных file.This будет гарантировать, что компилятор знает расположение памяти типа. Вы должны будете проектировать свой проект соответствующим образом.

+2

Возможно, стоит упомянуть, что неполные типы иногда используются для инкапсуляции API. Они фактически заставляют пользователя получать доступ к структуре только через открытые функции API. Таким образом, альтернативой может быть добавление необходимых функций API вместо прямого доступа к членам. –

+0

@AmbrozBizjak: Хорошо сказано. Это действительно правда. Но это зависит от цели * *, * цели * и, наконец, * *. Мы не знаем ни одного из них, поскольку OP выбирает абстрактные имена, такие как 'A',' B' и т. Д. –

+0

то как насчет передовой декларации класса? как компилятор знает о макете памяти в этом случае? – Kenta

3

Для доступа к членам требуется полное определение. Вам нужно, чтобы include заголовок внутри b.cpp, а не только вперед-объявить struct (что дает неполный тип).

EDIT:

Форвардный заявления достаточно для:

class B; 
class C 
{ 
    B& b; 
    B* b; 
    B foo(); 
    foo(B b); 
}; 

, но не для

class B; 
class C 
{ 
    B b; //ERROR 
    B foo() 
    { 
     B x; //error 
     x.whatever(); //error 
     return B(); //error 
    } 
}; 
+0

, то как насчет передовой декларации класса? как компилятор знает о макете памяти в этом случае – Kenta

+0

@vivek ему не нужно. Если у вас есть только ссылки или указатели, или используйте класс как возвращаемый тип или передайте его как параметр, ему не нужно знать полное определение. –

+0

thankx за ответ брата .. , так что вы говорите, что компилятор ищет полную защиту только в том случае, если вы собираетесь для прямого объявления структуры. а для класса он знает автоматически ??? – Kenta

0

Вам нужно включить определение вашей структуры, где используются члены, или компилятор не знает, что это такое.

так что если у вас есть в b.cpp, это

func(mystruct &s) 
    { 
     s.a = 1; 
    } 

Компилятор прекрасно, пока он не дойдет до назначения. В этот момент он пытается найти определение «a» внутри «mystruct» и не может его найти.

Вы должны #include "a.h" в b.cpp или, возможно, в зависимости от того, что еще находится в a.h, вам может понадобиться отдельный заголовок для структуры и включить его.

+0

, то как насчет передовой декларации класса? здесь нам не нужно включать заголовочный файл для соответствующего класса? – Kenta

+0

Я не сказал alter b.h, я сказал alter b.cpp. Вы можете использовать форвардное объявление, где компилятору не нужно ничего знать о содержимом структуры, но когда вы обращаетесь к содержимому, ему явно нужна эта информация. –

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