类的常量对象的定义

时间:2011-11-20 15:33:43

标签: c++ class

有这样的代码:

class MojaKlasa{
public:
};

int main()
{
  const MojaKlasa a;

  return 0;
}

编译错误是:

error: uninitialized const ‘a’

但是修改了MojaKlasa课程后:

class MojaKlasa{
public:
  MojaKlasa(){}
};

它可以正常工作。默认构造函数应该由C ++自动定义 - 为什么不在这种情况下完成,并且必须显式定义默认构造函数?

3 个答案:

答案 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。