为什么包含const数据成员的类没有默认构造函数

7

为什么编译器不会为包含常量数据成员的类添加默认构造函数。 请看下面的代码,在其中我声明了常量数据成员'a',当尝试创建一个类“ClassA”的对象时,它会显示“没有适当的默认构造函数可用”。请帮忙。

#include "stdafx.h"
#include <iostream>
using namespace std;

class ClassA
{
    private:
  const int a;
    public :
  void print()
  {
      cout << "hello world" << endl;
  }
};

int main()
{
  ClassA obj;
  obj.print();
  return 0;
}

4
你需要初始化变量 a - chris
尽管在其他地方有评论,但a的明显初始化是使用默认初始化程序,即int(),它将以零进行初始化。是的,这几乎是无意义的,但是否有人可以提供为什么默认构造函数不可能的参考资料? - Keith
@Keith 这只是语言的选择。内置数据成员默认情况下不会被初始化。 - juanchopanza
@juanchopanza。当然,那么为什么缺少初始化问题只是因为'a'是“const”? - Keith
这个问题在 C# 中得到了解决,通过让编译器强制开发者在行内初始化 const 变量。 - Ken D
显示剩余3条评论
5个回答

5

C++03规则在12.6.2/4 [class.base.init]中指定。如果一个类的非静态成员没有在构造函数的成员初始化列表中提及,那么如果它是const限定的,则必须是非POD类类型,并具有用户声明的构造函数,否则程序将是不合法的。隐式定义的构造函数使用空的成员初始化列表(和空的函数体)定义,因此,在这种情况下,导致隐式声明的默认构造函数被隐式定义,也会使程序不合法。

C++11规则等同于C++03。未在成员初始化列表中指定的非静态数据成员将被默认初始化。在C++11 8.5/6 [dcl.init]中,“[...] 如果程序调用一个带有用户提供的默认构造函数的const限定类型T的对象的默认初始化”,这在本例中归结为相同的规则。


3

由于常量值在初始化后不能更改,因此默认构造函数如何为其选择值。因此,默认构造函数不会被创建。


2

由于a是一个const变量,因此您可以将其声明为静态变量并进行初始化,而无需使用构造函数,如下所示:

class ClassA
{
    private:
    const static int a=10;
    public :
    void print()
    {
      cout << "hello world" << endl;
    }
};

int main()
{
  ClassA obj;
  obj.print();
  return 0;
}

1
在C或C++中,类型int没有默认值,因此a的值将是未定义的。例如,如果在调试模式下运行VC ++,则会使用不同的默认值填充a的值,而在发布模式下运行时则不会。在调试模式下,VC ++会使用以下值填充未初始化的内存:0xCCCCCCCC - 由Microsoft的C ++调试运行时库和许多DOS环境用于标记未初始化的堆栈内存;0xCDCDCDCD - 由Microsoft的C / C ++ debug malloc()函数用于标记未初始化的堆内存,通常从HeapAlloc()返回。因此,如果不初始化a,则每次运行程序都会有不同的常量值。

0

我相信你必须在构造函数中明确初始化常量成员,你必须在某个地方设置它们,而由于它们是常量,因此您可以随时在任何地方设置!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接