effective c++ item04:确定对象被使用之前以先被初始化

Item04 确定对象被使用之前已被初始化

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> thePhone;
  int numTimesConsulted;

};			//头文件内定义

ABEntry::ABEntry(const std::string& name,const std::string& address, const std::list<PhoneNumber>& phones){
  theName=name;
  theAddress=address;
  thePhones=phones;
  numTimesConsulted=0;
}

C++规定,对象的成员变量的初始化动作发生在进入构造函数主体之前。

在ABEntry构造函数内,theName,theAddress和thePhone都不是被初始化而是被赋值。他首先调用default构造函数为theName,theAddress和thePhone设初值,然后立刻再对他们赋予新值。default构造函数的一切作为浪费了。

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)的做法避免了这一问题,因为初值列中针对各个成员变量而设的实参,被拿去作为各成员变量之构造函数的实参。本例只调用一次copy构造函数是比较高效的。


C++有着十分固定的“成员初始化次序”。初始化array时需要指定大小,因此代表大小的那个成员变量必须现有初值。

 

不同编译单元内定义之non-local static对象的初始化次序

C++对此并无明确定义。

 

static对象,其寿命从被构造出来知道程序结束,因此staack和heap-based对象被排除。这种对象包括global对象、定义于namespace作用域内的对象、在class内、在函数内(local static)、以及在file作用域内被声明为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();				//使用tfs对象
}
Directory tempDir(params);					//为临时文件而做出的目录


tfs必须在tempDir之前先被初始化,但tfs和tempDir是不同的人在不同的时间于不同的源文件建立起来的,他们是定义于不同编译单元内的non-local static对象,其次序无法确定。

解决办法:将每个non-local static对象搬到自己的专属函数内(该对象在次函数内被声明为static).这些函数返回一个reference指向它所含的对象。non-local static对象被local static对象替换了。

此技术施于tfs和tempDir身上:


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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值