未初始化的对象
如果定义一个int型变量没有初始化,
int a;
在某些编译器上不会通过编译, 会有一个uninitialized local variable 的编译错误。 如果在类中有一个未初始化的成员变量, 则成员变量的状态为未定义:
class Test
{
public:
int a, b;
};
我们的处理办法是永远在使用对象之前将其初始化,对于内置类型,可以手动初始化:
int a = 0;
自定义类型的对象, 需要使用构造函数来进行初始化:
ABEntry::ABEntry(const std::string& name, const std::string& address,
const std::list<PhoneNumber>& phones)
{
theName = name;
theAddress = address;
thePhones = phones;
numTimesConsulted= 0;
}
上面的做法并不是最佳做法,因为成员变量实际并不是被初始化, 而是被赋值,最佳的方法是使用初始化成员列表(member initialization list)
ABEntry::ABEntry(const std::string& name, const std::string& address,
const std::list<PhoneNumber>& phones)
: theName(name)
, theAddress(address)
, thePhones(phones)
, numTimesConsulted(0)
{
}
第一种方法实际调用了一次默认构造函数, 并进行了赋值, 第二种直接调用了复制构造函数, 因此从效率上来讲, 第二种的效率较高。
在c++的初始化次序中, base class总是最先被初始化, derived class后被初始化,而class成员以其被声明的次序初始化,
不同编译单元内non-local static 对象的初始化
static 对象的寿命为从构造出来到程序结束为止, 非函数内生命的静态变量被称为non-local static 变量,程序结束时对象会被自动销毁, 析构函数在main()结束之后被调用, 编译单元是指产出单一目标文件的源码, 如果我们有两个源码文件,每一个都含有non-local static 变量,问题在于如果一个文件中的变量使用了另一个文件中的变量, 而用到对象时变量尚未初始化, 就会 产生问题,
class FileSystem
{
public:
...
std::size_t numDisks() const;
...
};
extern FileSystem tfs;
class Directory
{
public:
Directory(params);
...
};
Directory::Directory(params)
{
...
std::size_t disks = tfs.numDisks();
...
}
我们无法保证哪个变量会先被初始化,为了解决这个问题,我们可以使用设计模式中的singleton模式,
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;
}
这样就可以保证, 函数内的local static对象会在该函数被调用期间时被初始化。
|