Effective C++ Item 04: 确定对象初始化

未初始化的对象

如果定义一个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对象会在该函数被调用期间时被初始化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值