036-成员初始化列表
通常我们需要初始化一个类中的成员变量的时候,都是在构造函数内初始化的,在C++中也可以这样,例如
#include <iostream>
class Person {
private:
std::string mName;
public:
Person() {
mName = "Unknown";
}
Person(const std::string& name) {
mName = name;
}
const std::string &getName() const {
return mName;
}
};
int main() {
Person p0;
std::cout << p0.getName() << std::endl;
Person p1("张三");
std::cout << p1.getName() << std::endl;
return 0;
}
F:\Projects\ClionProjects\test\cmake-build-debug-cygwin\test.exe
Unknown
张三
进程已结束,退出代码为 0
能跑,不错
我们使用成员初始化列表后
#include <iostream>
class Person {
private:
std::string mName;
int mAge;
public:
Person() : mName("UnKnown"), mAge(1) {}
Person(const std::string &name, int age) : mName(name), mAge(age) {}
const std::string &getName() const {
return mName;
}
const int &getAge() const {
return mAge;
}
};
int main() {
Person p0;
std::cout << p0.getName() << ", " << p0.getAge() << std::endl;
Person p1("张三", 18);
std::cout << p1.getName() << ", " << p1.getAge() << std::endl;
return 0;
}
F:\Projects\ClionProjects\test\cmake-build-debug-cygwin\test.exe
UnKnown, 1
张三, 18
进程已结束,退出代码为 0
效果一样
注意:在使用成员初始化列表的时候,按照成员变量的定义顺序来,否则可能会有问题
那么,为什么要使用成员初始化列表呢,首先,代码好看了,还有关键的一点,如果是类对象,使用上面的方式就会初始化两次,造成内存浪费,看下面的例子
#include <iostream>
class Pet {
public:
Pet() {
std::cout << "Init pet without age" << std::endl;
}
Pet(int age) {
std::cout << "Init pet with age " << age << std::endl;
}
};
class Person {
private:
std::string mName;
Pet mPet;
public:
Person() : mName("UnKnown") {
mPet = Pet(8);
}
const std::string &getName() const {
return mName;
}
};
int main() {
Person person;
return 0;
}
看起来没啥毛病,但是运行结果为
F:\Projects\ClionProjects\test\cmake-build-debug-cygwin\test.exe
Init pet without age
Init pet with age 8
进程已结束,退出代码为 0
想不到吧,因为上面的Pet mPet
其实也进行了一次初始化,使用成员初始化列表后
#include <iostream>
class Pet {
public:
Pet() {
std::cout << "Init pet without age" << std::endl;
}
Pet(int age) {
std::cout << "Init pet with age " << age << std::endl;
}
};
class Person {
private:
std::string mName;
Pet mPet;
public:
Person() : mName("UnKnown"), mPet(Pet(8)) {
}
const std::string &getName() const {
return mName;
}
};
int main() {
Person person;
return 0;
}
运行结果
F:\Projects\ClionProjects\test\cmake-build-debug-cygwin\test.exe
Init pet with age 8
进程已结束,退出代码为 0
正常多了,另外, mPet(Pet(8))
也可以写为mPet(8)
也是没问题的