C++ 类参数初始化



C++ 中类的参数初始化列表

初始化列表用于初始化数据成员,语法以冒号 (:) 开头,然后是每个变量及其值,以逗号分隔,初始化列表不以分号结尾语法:

Constructorname(datatype value1, datatype value2):datamember(value1),datamember(value2)
{
    ...
}

例如:

#include<iostream>
using namespace std;

class Base
{
private:
    int value;
public:
    // 构造函数
    Base(int value):value(value)
    {
        cout << "Value is " << value;
    }
};

int main()
{
    Base il(10);
    return 0;
}

以上实例输出结果:

Value is 10

上面的代码只是一个示例,用于理解参数初始化列表的语法,在上面的代码中,value 也可以很方便地在构造函数中初始化,因此我们不必使用初始化列表。



C++ 中初始化列表的使用

在某些情况下,构造函数内的数据成员初始化不起作用,必须使用初始化列表,比如:



1) 当不存在基类默认构造函数时

在继承中首先调用基类的构造函数(构造函数调用顺序),然后是子类的构造函数。

因此,在下面的示例中,Base_ 类构造函数会在子类InitilizerList_ 类构造函数之前调用,因此下面的程序将抛出编译错误:"No default constructor exists for 类 Base_"

#include<iostream>
using namespace std;

class Base_
{
public:
    // 带参数的构造函数
    Base_(int x)
    {
        cout << "Base类构造函数. Value的值为: " << x << endl;
    }
};

class InitilizerList_:public Base_
{
public:
    // 默认构造函数
    InitilizerList_()
    {
        Base_ b(10);
        cout << "InitilizerList_类的构造函数" << endl;
    }
};

int main()
{
    InitilizerList_ il;
    return 0;
}

上面的代码可以使用初始化列表的方法重写,并且将顺利执行而不会出现任何错误。 这是新代码:

#include<iostream>
using namespace std;

class Base_
{
public:
    // 带参数的构造函数
    Base_(int x)
    {
        cout << Base类构造函数. Value的值为: " << x << endl;
    }
};

class InitilizerList_:public Base_
{
public:
    // 使用初始化列表的构造函数
    InitilizerList_():Base_(10)
    {
        cout << "InitilizerList_类的构造函数" << endl;
    }
};

int main()
{
    InitilizerList_ il;
    return 0;
}

以上实例输出结果:

Base类构造函数. Value的值为:  10
InitilizerList_类的构造函数


2) 使用引用类型时

如果你有一个数据成员是引用类型,则必须在初始化列表中对其进行初始化,引用是不可变的,因此它们只能被初始化一次。

#include<iostream>
using namespace std;

class Base
{
private:
    int &ref;
public:
    Base(int &ref):ref(ref)
    {
        cout << "Value的值为" << ref;
    }
};

int main()
{
    int ref=10;
    Base il(ref);
    return 0;
}

以上实例输出结果:

Value的值为10


3) 用于初始化 const 数据成员

const 数据成员只能初始化一次,因此必须在初始化列表中进行初始化。

#include<iostream>
using namespace std;

class Base
{
private:
    const int c_var;
public:
    Base(int c_var):c_var(c_var)
    {
        cout << "Value的值为" << c_var;
    }
};

int main()
{
    Base il(10);
}

以上实例输出结果:

Value is 10


4) 当数据成员和参数同名时

#include<iostream>
using namespace std;

class Base
{
private:
    int value;
public:
    Base(int value):value(value)
    {
        cout << "Value的值为" << value;
    }
};

int main()
{
    Base il(10);
    return 0;
}

以上实例输出结果:

Value的值为10


5) 用于提高性能

如果你在构造函数内分配值,则会创建一个临时对象,该对象将提供给赋值运算符,临时对象将在赋值语句结束时被销毁,而使用初始化列表可以避免创建临时对象。