有这样的代码:
class MojaKlasa{
public:
};
int main()
{
const MojaKlasa a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器错误是:
error: uninitialized const ‘a’
Run Code Online (Sandbox Code Playgroud)
但是在修改了MojaKlasa课程之后:
class MojaKlasa{
public:
MojaKlasa(){}
};
Run Code Online (Sandbox Code Playgroud)
它可以正常工作.默认构造函数应该由C++自动定义 - 为什么不在这种情况下完成,并且必须显式定义默认构造函数?
草案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.
Run Code Online (Sandbox Code Playgroud)
对于C++ 03,措辞如下(§8.5/ 9):
如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化; 如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数.否则,如果没有为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值; 如果对象或其任何子对象是const限定类型,则程序格式错误.
这就解释了为什么会这样.你有一个你没有初始化的POD类型,所以它的成员有一个"不确定"的值.由于您声明的对象是const
,您无法分配给它的字段,因此您将留下一个POD,其值无法分配给您,并且您无法从中读取(将是未定义的行为).不是很有用.