1、类成员初始化
C++ 中,构造函数可以通过两种方式对类成员进行初始化,可以使用成员初始化列表(推荐),也可以使用使用赋值语句。
1)使用成员初始化列表
成员初始化列表更高效,初始化列表直接调用成员的构造函数初始化成员变量。如果使用赋值语句,成员变量会先默认初始化(调用默认构造函数),再被赋值,这可能导致两次构造,效率低。
#include <iostream>
#include <string>
using namespace std;
class MyClass {
int x;
std::string name;
public:
// 构造函数:使用成员初始化列表
MyClass(int a, std::string n) : x(a), name(n) {}
// 添加成员访问函数
void display() const {
std::cout << "x: " << x << ", name: " << name << std::endl;
}
};
int main() {
// 创建对象,自动调用带成员初始化列表的构造函数
MyClass obj(42, "Alice");
// 调用成员函数输出内容
obj.display();
return 0;
}
2)使用赋值语句
#include <iostream>
#include <string>
using namespace std;
class MyClass {
int x;
std::string name;
public:
// 构造函数,不使用成员初始化列表
MyClass(int a, std::string n) {
x = a;
name = n;
}
// 成员函数,用于显示成员变量
void display() const {
std::cout << "x = " << x << ", name = " << name << std::endl;
}
};
int main() {
// 创建对象并传入参数
MyClass obj(42, "Example");
// 调用成员函数输出成员信息
obj.display();
return 0;
}
2、某些类型必须通过初始化列表初始化
const
成员变量,引用类型(T&
),没有默认构造函数的成员对象等必须通过初始化列表初始化。
#include <iostream>
#include <string>
using namespace std;
class MyClass {
const int id; // 常量成员,必须在初始化列表中初始化
int& ref; // 引用成员,也必须在初始化列表中初始化
public:
MyClass(int i, int& r) : id(i), ref(r) {}
void display() const {
std::cout << "id = " << id << ", ref = " << ref << std::endl;
}
void updateRef(int newVal) {
ref = newVal; // 修改的是原始变量的值
}
};
int main() {
int value = 42;
MyClass obj(1, value);
obj.display(); // 输出: id = 1, ref = 42
obj.updateRef(100);
obj.display(); // 输出: id = 1, ref = 100
std::cout << "Original value: " << value << std::endl; // 输出: 100
return 0;
}
3、可以避免默认构造的问题
对于没有默认构造函数的成员对象,使用赋值语句会导致编译错误,而初始化列表可以直接调用参数构造函数。
#include <iostream>
using namespace std;
class NoDefault {
public:
NoDefault(int x) {
std::cout << "NoDefault constructed with value: " << x << std::endl;
}
};
class A {
NoDefault nd;
public:
A() : nd(10) { // 使用成员初始化列表初始化 nd
std::cout << "A constructed" << std::endl;
}
};
int main() {
A a; // 创建 A 对象,将调用 NoDefault(10)
return 0;
}