C++构造函数使用冒号’:’初始化成员变量

Posted by Tango on November 28, 2015

C++构造函数后根据冒号’:’的作用是初始化对象的成员变量,但这个初始化方式与构造函数初始化成员变量有些差别:构造函数中无法对常量成员与引用成员进行初始化,而使用冒号方式可以解决这个问题,下面看个例子:

class A
{
public:
        A(int &c)
        {
                n = 1;
                m = n;
        }
        const int n;
        int &m;
};

使用g++编译会报出以下错误:

Construct.cpp: In constructor ‘A::A(int&)’:

Construct.cpp:4:2: error: uninitialized member ‘A::n’ with ‘const’ type ‘const int’ [-fpermissive]

A(int &c)

Construct.cpp:4:2: error: uninitialized reference member ‘A::m’ [-fpermissive]

Construct.cpp:6:5: error: assignment of read-only member ‘A::n’

大致意思就是两点:

  • 未初始化的常量
  • 未初始化的引用

而我们对这样的成员变量应该像以下初始化:

class A
{
public:
        A(int &c):n(1),m(c)
        {
        }
        const int n;
        int &m;
};

那么为何使用使用冒号形式可以初始化这些成员变量而构造函数不可以呢?

因为常量与引用类型必须在初始化的时候赋值。对于执行到构造函数,那么对象已经被分配好空间,构造函数是在对象分配好之后执行的代码预定操作,所以在构造函数中对常量与引用赋值是会报错的。

构造函数后的分号,是实际意义上的初始化,于构造函数之前执行。

看下面这段代码可以说明这个问题:

#include <iostream>
class A
{
public:
        A(int &c):n(c),m(c)
        {
                std::cout << n << std::endl;
        }
        const int n;
        int &m;
};

int main()
{
        int num = 10;
        A a(num);
}