1. 构造函数内成员变量初始化顺序
C++中创建一个新的类对象时,新对象的成员变量初始化顺序只与成员变量的定义顺序有关,与成员变量初始化列表顺序无关。
例如:
点击(此处)折叠或打开
class ABEntry {
public:
ABEntry():b(1), c(2), a(b) {}
private:
int a;
int b;
int c;
};
构造函数初始化顺序为a->b->c, 所以新对象成员变量a的值是不确定的,b = 1, c = 2.
2. 解决 “跨编译单元之初始化” 问题,以local static对象替换non-local static对象。
点击(此处)折叠或打开
class FileSystem {
public:
...
std::size_t numDisks() const;
...
};
extern FileSystem tfs;
若全局变量tfs在未完成构造初始化之前被其他地方使用,可能导致灾难后果。例如:
点击(此处)折叠或打开
class Directory {
public:
Directory(params);
...
};
Directory::Directory()
{
...
std:size_t disks = tfs.numDisks();
...
}
创建一个Directory对象,用来防止临时的文件:
Directory tempDir(params);
除非tfs在tempDir之前先被初始化,否则tempDir的构造函数会用到尚未初始化的tfs。
但tfs和tempDir是不同的人在不同的时间于不同的源码文件建立起来的,他们是定义于不同编译单元内的non-local static对象。如何确定tfs会在tempDir之前先被初始化?
消除该问题的做法是:将每个non-local static对象搬到自己的专属函数内(该对象在此函数内被声明为static)。
C++保证,函数内的local static对象会在函数被调用期间,首次遇上该对象定义式时被初始化。
点击(此处)折叠或打开
class FileSystem { ... } //同前
FileSystem &tfs()
{
static FileSystem fs;
return fs;
}
class Directory { ... }
Directory::Directory(params)
{
...
std::size_t disks = tfs().numDisks();
...
}
Directory &tempDir()
{
static Directory td;
return td;
}
该类函数需注意在多线程环境下使用,static成员在多线程环境下具有不确定性。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2370/viewspace-3150360/ ,如需转载,请注明出处,否则将追究法律责任。