类的有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员, 在构造函数函数体中对他们赋值不起作用。这样类型的成员有:没有默认构造函数的类类型的成员, const或引用类型的成员(不管他们本身是什么类型的,如int &a或是string &a), 都必须在构造函数初始化列表中进行初始化。如下例:
[cpp]
view plain
copy
- #include <cstdlib>
- #include <iostream>
- #include <string>
- using namespace std;
- class Name
- {
- public:
- Name(string str) : m_first(str), m_last(str){};
- private:
- string m_first;
- string m_last;
- };
- class Person
- {
- public:
- /*Person(string str, int id, int gend)
- {
- m_id = id; //main.cpp uninitialized reference member `Person::m_id'
- m_gend = gend; //main.cpp no matching function for call to `Name::Name()'
- m_name = str;//main.cpp uninitialized member `Person::m_gend' with `const' type `const int'
- }*/
- //right
- Person(string str, int id, int gend) : m_name(str), m_id(id), m_gend(gend){};
- private:
- int &m_id;
- Name m_name;
- const int m_gend;
- };
- int main(int argc, char *argv[])
- {
- Person per("tom", 1, 2);
- system("PAUSE");
- return EXIT_SUCCESS;
- }
构造函数初始化列表仅用于初始化成员的值, 并不指定这些初始化执行的次序。成员被初始化的次序就是定义成员的次序。如下例:
[cpp]
view plain
copy
- #include <cstdlib>
- #include <iostream>
- using namespace std;
- class Try
- {
- public:
- Try(int val) : m_i(val), m_j(m_i){};
- private:
- int m_j;
- int m_i;
- };
- int main(int argc, char *argv[])
- {
- Try try(8);
- system("PAUSE");
- return EXIT_SUCCESS;
- }
以上程序在初始化成员时, 并不是按照初始化列表的次序先初始化m_i, 然后m_j, 而是按照这两个成员定义时的次序, 先初始化m_j, 在m_i, 于是出现了问题, 在初始化列表中m_j(m_i), 也就是想用m_i去初始化m_j ,但这是m_i还没有被初始化, 所以会出现编译错误…
C++ primer中推荐:最好按照与成员声明一致的次序编写初始化列表。而且, 尽可能的避免使用类成员去初始化其他类成员。
如果没有按照定义顺序初始化的时候,会提示如下warning
will be initialized after
when initialized here
调整后,此warning消失