为什么类可以在成员函数定义中使用,但在用作成员时被视为不完整
Why can a class be used within itself in member function definition, but is regarded as incomplete when used as a member?
class A
{
private:
A a;
};
为什么类中的 A 是不完整的类型?
class A
{
public:
A& operator= (A a){return *this;}
};
operator=
的参数A
不是不完整的类型吗?为什么上面的代码会编译?
因为在类定义中的开放空间中使用A
与在成员函数定义的参数列表中使用它之间存在差异。这是两个不同的范围。
[C++11: 9.2/2]:
类在类说明符的结束}
被视为完全定义的对象类型 (3.9((或完整类型(。在类成员规范中,类在函数体、默认参数、异常规范和非静态数据成员(包括嵌套类中的此类内容(的大括号或等于初始值设定项中被视为完整的。否则,它在其自己的类成员规范中被视为不完整。
然后是以下特殊情况:
[C++11: 8.3.5/9]
:类型不得在返回或参数类型中定义。参数的类型或函数定义的返回类型不应是不完整的类类型(可能是 cv 限定的(,除非函数定义嵌套在该类的成员规范中(包括类中定义的嵌套类中的定义(。
">
原来如此。">实际上,很明显不可能在A
中存储A
(因为这需要无限封装(,而在成员函数的参数列表中显然并非如此。因此,标准委员会有机会让我们更容易一点,他们抓住了它。
此外,如果您尝试在函数的定义中使用 a
的成员,那么这也是允许的(根据上面的第一个引号(,就好像该函数是在类定义结束后以词法方式声明的一样。
在一般情况下,第一个块是不可能的,因为要知道sizeof(A)
是什么(对于类(,它需要知道sizeof(A)
是什么(对于成员(。
第二种情况的不同之处在于,即使成员函数的定义在语法上在类内部,语言也会认为该定义在类之外。 编译器将翻译该代码,就像您键入它一样:
class A {
public:
A& operator=(A a);
};
inline A& A::operator=(A a) { return *this; }
声明函数接受或返回不完整类型的对象是合法的。 当类型真正被使用时,在类之外的函数定义中,类型已经完成,所以它也完全没问题。
看待这个问题的方法是了解如果这实际上是合法的会发生什么。实例化类时,首先构造其所有类成员。因此,在您的示例中,A a
的构造将在 A 完全构造之前进行,这是不可能的。
此外,这将导致 A 对象的无限递归构造。
第二个是编译,因为你只使用A的引用而不是A的对象。但是在第一种情况下,您需要 A 的对象,因此需要完整的类型,这只能在关闭 } 后发生
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法