1.成员初始化列表
2.初始化对象
1.成员初始化列表
1).成员初始化列表简介
成员初始化列表是构造函数的一部分, 位于构造函数参数列表之后, 函数体{
}之前, 用:开头
多个成员之间用","分隔, 直接对成员变量进行初始化
#include <string>
using namespace std;
class Person {
private:
int age;
string name;
const int id;
int& score;
public:
Person(int a, string n, int i, int& s) : age(a), name(n), id(i), score(s) {
}
};
2).为什么必须用初始化列表
C++语法规定, 以下类型的成员变量无法在构造函数体内赋值, 必须在初始化列表中初始化
a.const成员变量: const修饰的变量只读, 必须在创建时(初始化阶段)赋值, 不能后续修改
b.引用成员变量: 引用是变量的别名, 必须在创建时绑定到一个对象, 不能先创建再赋值
class Circle {
private:
const double PI;
double& radius;
double area;
public:
Circle(double& r) : PI(3.14159), radius(r) {
area = PI * r * r;
}
};
int main() {
double r = 5.0;
Circle c(r);
return 0;
}
c.没有默认构造函数的类类型成员: 如果成员是另一个类的对象, 且该类没有默认构造函数, 则
必须通过初始化列表传参构造
d.基类构造函数需要传参: 继承时, 基类没有默认构造函数, 必须在子类初始化列表中调用基类
带参构造
class Base {
private:
int baseVal;
public:
Base(int val) : baseVal(val) {
}
};
class Derived : public Base {
private:
int derVal;
public:
Derived(int bVal, int dVal) : Base(bVal), derVal(dVal) {
}
};
e.避免二次构造, 提升效率
对于类类型成员(如string、vector、自定义类), 初始化列表会直接调用其构造函数创建对
象; 而构造函数体内赋值, 会先调用默认构造函数创建对象, 再调用赋值运算符, 相当于创建 +
赋值两步操作, 浪费性能
#include <string>
#include <iostream>
using namespace std;
class Test {
public:
string str;
Test(string s) : str(s) {
cout << "初始化列表:str直接构造" << endl;
}
Test(string s, bool flag) {
str = s;
cout << "体内赋值:str先默认构造,再赋值" << endl;
}
};
int main() {
Test t1("hello");
Test t2("world", true);
return 0;
}
3).初始化列表中成员的书写顺序由"成员在类中声明的顺序决定"
class WrongOrder {
private:
int a;
int b;
public:
WrongOrder(int val) : a(val1), b(va2) {
}
};
int main() {
WrongOrder wo(10);
return 0;
}
2.初始化对象