C++ 成员初始化列表

发布时间 2023-08-20 16:37:36作者: OrzMiku

成员初始化列表

成员初始化列表时对象初始化成员变量的一种方法。使用方式如下(两种书写习惯)

ClassName(args): varName1(value), ... , varNameN(value){
    // 这是一个构造函数
    // ...CODE...
}

ClassName(args)
    : varName1(value), ... , varNameN(value){
    // 这是一个构造函数
    // ...CODE...
}

注意:C++ 初始化类成员时,是按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序。

下面是一段代码:

#include<iostream>

using namespace std;

class Example {
public:
	Example() {
		cout << "The Example Class is loaded." << endl;
	}
	Example(string str) {
		cout << "The Example Class is loaded with " << str << "." << endl;
	}
};

class Entity {
private:
	string m_name;
	Example m_e;
public:
	Entity()
		:m_name("Unknowen") {
		m_e = Example("Test");
	}

	Entity(string name)
		: m_name(name) {}
	string getName() const {
		return m_name;
	}
};

int main() {
	Entity e;
	return 0;
}

在这段代码中,我们使用了成员初始化列表给 m_name 做了初始化。但是 m_e 没有使用。

这段代码运行后,输出了:

The Example Class is loaded.
The Example Class is loaded with Test.

可见我们实例化了两个Example对象。在声明 m_e 时创建了一个。在给 m_e 初始化时创建了一个。之前的对象完全被丢掉了,使用了新的对象。这样就造成了性能损失。我们可以通过成员初始化列表来避免这个问题。

修改后的代码如下:

#include<iostream>

using namespace std;

class Example {
public:
	Example() {
		cout << "The Example Class is loaded." << endl;
	}
	Example(string str) {
		cout << "The Example Class is loaded with " << str << "." << endl;
	}
};

class Entity {
private:
	string m_name;
	Example m_e;
public:
	Entity()
		:m_name("Unknowen"),m_e(Example("Test")) {}

	Entity(string name)
		: m_name(name) {}
	string getName() const {
		return m_name;
	}
};

int main() {
	Entity e;
	return 0;
}

这段代码的运行结果为:

The Example Class is loaded with Test.

相同的,诸如string类型(类)的变量在初始化时也可能出现这种情况。虽然基础类型(诸如int,double等)不会出现这种情况,不过还是推荐统一使用成员初始化列表来做初始化。