在“C++ primer”一书中,有关于类声明和定义的章节。我不明白这句话的所有内容:为什么只有在定义了类时才能将数据成员指定为类类型? (来自“C++ primer”一书)
只有在类已定义的情况下,才能将数据成员指定为类类型。
我不明白这句话背后的逻辑。如何将数据成员指定为类类型,此操作是什么意思?
在“C++ primer”一书中,有关于类声明和定义的章节。我不明白这句话的所有内容:为什么只有在定义了类时才能将数据成员指定为类类型? (来自“C++ primer”一书)
只有在类已定义的情况下,才能将数据成员指定为类类型。
我不明白这句话背后的逻辑。如何将数据成员指定为类类型,此操作是什么意思?
这意味着,对于类型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
};
我认为这意味着这将编译:
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!
};
你甚至不需要在A. –
或B的括号之间的任何东西。评论总是可选的,但在这种情况下,这是一个很好的做法,这样读者就不会认为你想把东西放在那里,但忘记了。 –
我的意思是全班的A,而不仅仅是Ctor。为了使这个答案有意义,你需要B中的_something_;具体而言,是一个A类型的字段,但是A内部不需要任何东西。另外,我不计算评论,尽管我原来的评论并不明确。我的意思是你不需要任何实际的代码。 –
这意味着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;
};
类类型是由一个'class'或'struct'表示的类型,而不是内置型。这句话意味着只有在类已经被定义的情况下,成员才可以是类类型的,即不仅仅是前向声明。但是,您可以拥有指向不完整类型的指针或引用。 –