28 页
C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。
构造函数的一个较佳的写法是,使用所谓的member initialization list替换赋值动作。
29页
但请立下一个规则,规定总是在初值列中列出所有成员变量,以免还得记住哪些成员变量可以无需初值。
31页
幸运的是一个小小的设计便可以完全消除这个问题。将每个non-local static对象搬到自己的专属函数内(改对象在此函数内被声明为static)。这些函数返回一个reference指向它所含的对象。然后用户调用这些函数,而不直接指涉这些对象。
换句话说,non-local static对象被local static对象替换了。Design Patterns fans想必认出来了,这个是Singleton模式的一个常见实现手法
1)为内置对象进行手工初始化,因为c++不保证初始化她们
2)构造函数最好使用member initialization list,而不要在构造函数本体内使用assignment。list列出的成员变量,起排列次序应该和他们在class中的声明次序相同。(不同的话也是合法的)
3)为避免“跨编译单元之初初始化次序”问题,请以local static对象替换non-local static对象。
#include <iostream>
#include <string.h>
using namespace std;
class PhoneNumber
{
public:
PhoneNumber(){cout << "in PhoneNumber
" ;}
};
class ABEntry
{
public:
ABEntry(){cout << "in ABEntry()
" ;};
ABEntry(const PhoneNumber & phone);
private:
PhoneNumber PN;
};
ABEntry::ABEntry(const PhoneNumber & phone)
{
cout << "in ABEntry(const ...)
" ;
PN = phone;
}
int main()
{
PhoneNumber pn;
cout << "in main 2
" ;
ABEntry ab;
cout << "in main 3
" ;
ABEntry ab2(pn);
return 0;
}
/work/ctest/effectivec++$ g++ 4_2.cpp -o 1 && ./1
in PhoneNumber
in main 2
in PhoneNumber
in ABEntry()
in main 3
in PhoneNumber
in ABEntry(const ...)
//甚至当你想要default构造一个成员变量,你都可以使用成员初值列,只要指定无物(nothing)作为初始化实参即可。
class PhoneNumber
{
public:
PhoneNumber(){cout << "in PhoneNumber
" ;}
};
class ABEntry
{
public:
ABEntry():PN(){cout << "in ABEntry()
" ;};
ABEntry(const PhoneNumber & phone);
private:
PhoneNumber PN;
};
ABEntry::ABEntry(const PhoneNumber & phone):PN(phone)
{
cout << "in ABEntry(const ...)
" ;
PN = phone;
}
int main()
{
PhoneNumber pn;
cout << "in main 2
" ;
ABEntry ab;
cout << "in main 3
" ;
ABEntry ab2(pn);
return 0;
}
in PhoneNumber
in main 2
in PhoneNumber
in ABEntry()
in main 3
in ABEntry(const ...)
2)