2013-05-31 3 views
7

У меня проблема с форвардной декларацией на C++ с использованием компилятора clang. Вот мой код. Он указывает данные в члене CReference как неполный тип. Пожалуйста, помогитеПередовая декларация класса в C++, неполный тип

class Internal; 

class CReference { 
private: 
    Internal data; 
public: 

    CReference() {}  
    ~CReference(){} 
}; 

class Internal { 
public: 
    Internal() {} 
    ~Internal() {} 
}; 
+0

Здесь вы просто не можете использовать декларацию. 'CReference' нуждается в полной декларации' Internal'. – juanchopanza

+0

Вы должны использовать указатель на 'Internal', если вы хотите переслать объявление. – user1520427

+1

Возможный дубликат [Когда использовать форвардную декларацию?] (Http://stackoverflow.com/questions/553682/when-to-use-forward-declaration) – juanchopanza

ответ

3

вперед заявление только позволяет использовать указатели и ссылки на него, пока полное описание не доступно

15

вперед декларации полезны, когда компилятор не требует полного определения типа. Другими словами, если вы измените свой Internal data; на Internal* data или Internal& data, он будет работать.

Используя Internal data;, компилятор должен знать всю информацию о Intrenal, чтобы иметь возможность создать структуру класса CReference.

+0

Почти идеальный ответ. Осталось только упомянуть, что он может переместить определение Internal выше CReference, и он будет работать. –

+0

@RickYorgason - конечно, но, я думаю, OP знает, что это выглядит очевидным, поскольку 'class Internal' не нужно« знать »о' class CReference'. –

1

Чтобы использовать тип как член класса, компилятор должен знать, насколько он велик, чтобы можно было правильно вычислить размер класса. В прямом объявлении не указывается эта информация (C++ не будет смотреть вперёд и попытаться ее найти, тем более, что тело может быть объявлено в другой единицы перевода), поэтому вы не можете использовать его как член по значению.

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

0

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

Как правило, вы хотите как можно меньше включать в заголовочные файлы. Это может быть достигнуто путем прямого объявления класса, но только в том случае, если он не является вложенным классом и только если указатель используется в заголовке, так как для этого размер указателя является необходимой информацией, которая предоставляется передним объявлением.

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