有这样的代码:
class MojaKlasa{
public:
};
int main()
{
const MojaKlasa a;
return 0;
}
编译错误是:
error: uninitialized const ‘a’
但是修改了MojaKlasa课程后:
class MojaKlasa{
public:
MojaKlasa(){}
};
它可以正常工作。默认构造函数应该由C ++自动定义 - 为什么不在这种情况下完成,并且必须显式定义默认构造函数?
答案 0 :(得分:7)
草案n3290(C ++ 0X)在§8.5/ 6中有这个:
默认初始化T类型的对象意味着:
- 如果T是(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(并且 如果T没有可访问的默认构造函数,则初始化是错误的;) - 如果T是数组类型,则每个元素都是默认初始化的;
- 否则,不执行初始化 如果程序要求默认初始化 const限定类型T 的对象,则T应为类类型 使用用户提供的默认构造函数。
所以你实际上需要一个用户定义的构造函数,编译器生成的构造函数是不够的。
BTW,clang++
对此有很好的诊断:
$ clang++ -std=c++0x -pedantic -Wall t.cpp
t.cpp:7:19: error: default initialization of an object of const type
'const MojaKlasa' requires a user-provided default constructor
const MojaKlasa a;
^
1 error generated.
对于C ++ 03,措辞如下(§8.5/ 9):
如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化;如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数。否则,如果没有为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值; 如果对象或其任何子对象是const限定类型,则程序格式错误。
这解释了为什么就是这样。你有一个你没有初始化的POD类型,所以它的成员有一个“不确定”的值。由于您声明的对象是const
,因此您无法分配其字段,因此您将留下一个POD,其值无法分配给您,并且您无法从中读取(将是未定义的)行为)。不太有用。
答案 1 :(得分:2)
当这样声明时,MojaKlasa
是POD类型,因此编译器无法自动将其初始化为任何有意义的值,就像它无法自动将const int
初始化为任何有意义的值一样
请注意,您不需要显式默认构造函数来创建此类型的常量:
const MojaKlasa foo = {}; // works fine
答案 2 :(得分:-2)
编译器可能会感到困惑,因为a的大小为零!尝试添加虚拟成员到MojaKlasa。