C++ 初始化列表和构造函数成员属性的区别
说明,除了以下四种情况,编译器强制要求采用初始化列表:
1 包含常量成员,必须初始化列表进行初始化
2 包含引用成员,必须初始化列表进行初始化
3 包含成员类对象,并且有显示构造函数,必须要初始化列表进行初始化
4 继承于基类,并且基类有显示构造函数,必须要初始化列表进行初始化
实例:
#include<iostream>
using namespace std;
class Word{
public:
Word(int _id, const int _age, string _name):id(_id),age(_age),name(_name){}
//常量成员和引用必须初始化列表进行初始化
// Word(int _id, const int _age)
// {
// id = _id;
// age = _age; // 常量成员只能初始化 不能赋值
// name = _name; // 引用成员只能初始化 不能赋值
// }
private:
int id;
const int age;
string &name;
};
class Article{
public:
// 包含成员 类对象并且有显示构造函数,必须要初始化列表进行初始化
Article(int _size):w(0,0," "),size(_size){}
//下面错误
// Article(int _size)
// {
// w(0,0,0);
// size = _size;
// }
private:
Word w;
int size;
};
class Article2:public Word{
public:
// 继承基类,并且基类有显示构造函数,必须要初始化列表进行初始化
Article2(int _size):Word(0,0," "),size(_size){}
private:
int size;
};
但是需要说明,函数体内进行类成员初始化,效率并不高:
class Word{
private:
string _name;
int _age;
public:
Word(string name, int age)
{
_name = name;
_age = age;
}
};
--->
// 编译器实现上面的初始化string成员的过程,
// 1 调用string的默认构造函数初始化_name
// 2 构建一个临时string对象temp
// 3 调用string的赋值运算符=
// 4 调用临时对象的析构函数
Word(string name, int age)
{
_name.string::string(); <- 1
string temp = string(name); <- 2
_name.string::operator=(temp); <- 3
temp.string::~string(); <- 4
_age = age;
}