2017-02-06 22 views
4

В книге «C++ primer» есть раздел о объявлениях классов и определениях. Я не понимаю всего об этом предложении:Почему данные могут быть указаны как тип класса только в том случае, если класс определен? (из книги «C++ primer»)

Элементы данных могут быть указаны как тип класса, только если класс был определен.

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

+1

Классовый тип является типом представлен 'class' или' struct', в отличие от встроенного типа. Предложение означает, что члены могут быть типа класса только в том случае, если этот класс определен, то есть не только объявлен вперед. Однако у вас могут быть указатели или ссылки на неполный тип. –

ответ

8

Это означает, что для декларирования нестатического элемента данных класса класса типа T, T требуется быть complete.

(В общем случае, когда размер и расположение T должны быть известны.)

например,

class foo; // forward declaration 
class bar { 
    foo f; // error; foo is incomplete 
}; 

С другой стороны,

class foo {}; // definition 
class bar { 
    foo f; // fine; foo is complete 
}; 
3

Я считаю, что это означает, что это будет компилировать:

class A 
{ 
public: 
    A() {/* empty */} 
}; 

class B 
{ 
public: 
    B() {/* empty */} 

private: 
    A myClassMember; // ok 
}; 

.... но это не будет:

class A; // forward declaration only! 

class B 
{ 
public: 
    B() {/* empty */} 

private: 
    A myClassMember; // error, class A has only been declared, not defined! 
}; 
+0

Вам не требуется ничего между скобками A. –

+0

Или B, если на то пошло. Комментарии всегда являются необязательными, но хорошая практика в этом случае, так что читатель не думает, что вы хотели что-то там положить, но забыл. –

+0

Я предназначался для всего класса A, а не только для ctor. Чтобы этот ответ имел смысл, вам понадобится _something_ в B; в частности, поле типа A, но вам ничего не нужно внутри A. Кроме того, я не считал комментарии, хотя мой первоначальный комментарий не был ясен; Я имел в виду, что вам не нужен настоящий код. –

2

Это означает, что эта спецификация member не действует, потому что A объявлен но не определен:

class A; 

class B { 
    A member; 
}; 

Одна из причин, почему это не допускается, является becau se sizeof(A) неизвестен.

Это, однако, справедливо, потому что A определяется:

class A { 
    int value; 
}; 

class B { 
    A member; 
}; 

И это справедливо, даже если A не определен (только декларируется), потому что member не относится к типу класса, но тип указателя:

class B { 
    A* member; 
}; 
Смежные вопросы