[英]Nested Class member function can't access function of enclosing class. Why?
[英]Why a nested class can't have a member the type of which is the one of the enclosing class?
一个的类的方法C
需要返回一个struct
包含一对整数和一个新鲜实例C
。 它可能看起来很尴尬,但考虑到整体设计,这很有意义(想想一个Waveform
类将一系列自身作为副本返回,并指示范围的开始和结束位置)。
问题是似乎不允许这样做。 我可以重新设计我的类以避免这个问题,但是你可以解释一下为什么从编译器的角度来看,这不可能做到
struct S {
struct S2 {
S s;
};
};
因为S
是一个不完整的类型(这是编译器错误),相反,这是完全正常的
struct C {
struct C1 {
C makeC() { return C(); }
};
};
哪里有实质性的区别?
在您尝试定义S::S2
,类型S
仍然是不完整类型 ,因为其定义尚未完成。 类数据成员必须具有完整类型。
您可以像这样轻松修复它:
struct S
{
struct S2; // declare only, don't define
// ...
};
struct S::S2
{
S s; // now "S" is a complete type
};
C ++的设计决定本质上是在完成定义之前不考虑类型完成。 这可以防止许多病理情况,例如以下示例:
struct X
{
struct Y { X a; };
int b[sizeof(Y)]; // "sizeof" requires a complete type
};
如果要定义类,则需要完整定义所有嵌入(非引用和非指针)成员。 在定义类时,类没有完全定义。 也就是说,在类定义中,定义的类仅仅是声明的,而不是定义的。
也就是说,您仍然可以在嵌套类中拥有类的成员。 您只需在定义外部类后定义嵌套类:
struct S {
struct S2;
};
struct S::S2 {
S s;
};
由于S
完全由第一个闭合支撑定义,因此在此之后它可以用作嵌入式构件。
在类定义中定义成员函数时,定义将被解析,就好像它出现在最接近的命名空间级别上的类定义之后。 也就是说,成员函数定义知道完全定义的类。 这同样适用于嵌套类。
我不确切知道为什么,但我可以推测这个反例:
struct S {
struct S2 {
S s;
};
S2 s2;
};
在这种情况下,在扫描S2
之前扫描S
并确定其大小的尝试将失败。 我怀疑递归可能会给编译器带来困难,而这些困难往往是标准中规则的原因。
也就是说,我认为您的解决方案不适合您所描述的问题。 我会在S
上制作S2
模板,而不是嵌套。 然后我将能够使用引用S&
作为模板参数,而不是S
本身。 因此,范围将由两个整数和对原始数组对象的引用表示。 从这个范围制作一个新的副本将是一个单独的操作。
编译器无法计算所包含类的大小。
你可以写S* s;
虽然。
这个答案着重于两个例子之间的区别 ,因为其他答案已经解释了为什么第一个例子不起作用。
简而言之,您的第一个示例在S
中使用S
,要求S
完成。
您的第二个示例要求在编译函数体后立即完成C
你的代码相当于
struct C {
struct C1 {
C makeC();
};
};
inline C C::C1::makeC() {
return C();
}
这意味着,编译器会自动“推迟”函数体。 对于函数声明 ,编译器只需要知道C
是一个类型,但如果C
不完整,那么它就可以工作,这就是那个点。 在编译函数定义时 ,类型C
现在已完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.