有些时候,我们会认为没有初始化没有关系,特别数组的初始化,认为不初始化没什么关系,但是有些时候,我们可能太依赖编译器了,因为有时候C++的标准没有做出规定,这个时候就依赖编译器了,你可能运行会得到正确的结果,但是这个放到其他地方很可能就出错。
步入正题:很可能你会觉得不就是个初始化, 简单。但是在这之前你应该知道什么叫初始化,我们直接讨论要自己构造的对象,因为内置类型的情况大家够比较的清楚
class PhoneNumber {...};
class ABEntry
{
public:
ABEntry(const std::string &name,const std::string &address,const std::list<PhoneNumber & phones>);
private:
std::string thename;
std::string theAddress;
std::list<PhoneNumber> thephones;
int numTimeConsulted;
};
ABEntry::ABEntry(const std::string &name,const std::string &address,const std::list<PhoneNumber & phones>)
{
thename=name;
theAddress=address;
thephones=phones;
numTimeConsulted=0;
}
这是初始化吗?不是对象的成员变量的初始化是在发生在进入构造函数本体之前,比较好的做法是使用初始化列表,效率也更高,前面赋值的版本是先调用成员的默认构造函数,进行获取初值,然后进入构造函数之后重新赋予新值,相比之下使用初始化列表及不存在这一问题,因为初始列表的做法是针对各个成员而设实参,去作为成员函数构造函数的实参,本例的thename以name为初值进行cpoy构造。对大多数类型而言这样是高效的,但是对于内置类型来说numTimeConsulted来说,成本是相同的。(注:成员变量的初始化顺序跟初始化列表的顺序无关,只跟声明的顺序有关)
ABEntry::ABEntry(const std::string &name,const std::string &address,const std::list<PhoneNumber & phones>)
:thename(name) ,theAddress(address),thephones(phones),numTimeConsulted(0)
{}
再考虑一种情况,成员变量是const或者reference,我们就必须使用初始化而不是赋值,原因就是这种变量如果不初始化,那就造成无法使用。
下面看看static:如果编译单元内的no-local-static对象初始化动作使用了另一个编译单元的no-local-static对象,C++对定义与不同编译单元的“no-local-static”对象初始化顺序无明确的定义,看一个例子:
class FileSystem
{
public:
std::size_t numDisk() const ;
};
extern FileSystem tfs;
class Directory
{
public:
Directory (params);
};
Directory:: Directory (params)
{
std::size_t disks=tfs.numDisk();
}
Directory tempdir(params);
如果tfs对象在tempdir之前没有初始化怎么办? 就会出现难以预料的情况。这种初始化顺序不能确定的情况下,需要通过以下的方法来解决。
将no-local-static对象搬到放到一个转速的函数内部,就是将no-local-static对象换成local-staic对象。回想一下单例模式是怎么干的?
class FileSystem{};
FileSystem &tfs() //注意这个 不是成员函数
{
static FileSystem fs;
return fs;
}
class Directory{};
Directory:: Directory (params)
{
std::size_t disks=tfs().numDisk();
}
Directory & tempdir()
{
static Directory td;
return td
}