2017-02-06 36 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。为了使这个答案有意义,你需要B中的_something_;具体而言,是一个A类型的字段,但是A内部不需要任何东西。另外,我不计算评论,尽管我原来的评论并不明确。我的意思是你不需要任何实际的代码。 –

2

这意味着member本规范是无效的,因为A声明但没有定义:

class A; 

class B { 
    A member; 
}; 

为什么不允许这样做的一个原因是因为se sizeof(A)是未知的。

然而,这是有效的,因为A定义:

class A { 
    int value; 
}; 

class B { 
    A member; 
}; 

这是合法的,即使A没有定义(仅申报),因为member不是类类型的,但是指针类型:

class B { 
    A* member; 
}; 
相关问题