Effective C++ 条款4——确定对象被使用前已先被初始化

 条款4——确定对象被使用前已先被初始化

   终于连上网了。过了几天没有网的日子还可以....现在手头有本More Effective C++打算边翻翻看这本书,边写日志复习 Effective C++

    这条规矩我想人人都知道,可是却时常被忘记。而我们的伙伴C++也常常淘气搞怪。比如说

     int x,这个有时候x被初始化了,有时候没有。在类中比如

class Point{
int x,y;
...
};
point P;

这个x,y就有时候会初始化为0,有时候又不会。要想分辨并记住这些不同情况比较麻烦,好,我们莫不如手工完成这件事——针对所有的内置类型

int x=0;
const char* text="hello world";
double d;
std::cin>>d;//以读取输入流的方式初始化。

赋值与初始化

那么针对其他自定义类型呢???这就是我们大名鼎鼎构造函数的任务了。首先呢大家先考虑一下什么是赋值(assignment)什么是初始化(initialization)。这个真的很容易混淆。

class PhoneNumber{...}
class EXAMPLE{
public:
EXAMPLE(const string& name,const string& address,const list<PhoneNumber>& phones)
private:
string theName;string theAddress;list <PhoneNumber> thePhones;int x;};

我们看到了上面的构造函数,如果我们这样

EXAMPLE::EXAMPLE(.....)
{
theName=name;//这是赋值,不是初始化
theAddress=address;//赋值
thePhones=phones;//赋值
x=0//当然这也是赋值
}

C++规定对象成员的变量初始化要在进入构造函数实现部分之前,也就是{...}之前(x除外,它是内置类型)C++给我们提供了以下的形式

EXAMPLE(const string& name,const string& address,const list<PhoneNumber>& phones)
:theName(name),
theAddress(address)//这些都是初始化
ThePhones(phones)
x(0)
{  }

其实这个两种构造函数效果相同,可是使用成员初值列的,也就是第二种,效率更高。为什么呢???下面就将隐藏在背后的东西告诉大家:

第一种:首先调用了string的默认构造函数对theName进行初始化,然后又用name这个变量对它赋值-------因为string也是个类

第二种:直接利用成员初值列,调用了string类中的copy构造函数,对theName进行初始化。------要理解copy构造函数和普通构造函数的话,推

C++中成员初始化次序是固定的。有继承的情况下类与类之间:先基类后子类

类内部:按照变量声明的次序,与初始化列表无关。

不同编译单元内的non-local static对象初始化次序问题  

所谓编译单元是指产出单一目标文件的源码。也就是一个源码文件+其头文件

所谓local static对象就是定义在函数内部的static,其他的对象就称为non-local static对象

现在的情况是一个编译单元的某个non-local static对象A初始化动作里使用了另一个编译单元内的某个non-local static对象B,我们无法保证B一定会在A之前已被初始化,C++不给我们这种保证。例如

在编译单元A内我们定义了一个文件系统类

class FileSystem{
public:
...
std::size_t numDisks() const;
...
};
extern FileSystem tfs;

在另一编译单元B内,客户建立另一个类

class Directory{
public:
Directory(params);
...
};
Directtory::Directory(params)
{
...
//用到了tfs对象
std::size_t disks=tfs.numDisks();
}

此时当我们创建一个Directory对象时

Directory tempDir(params);c++不保证tfs一定在tempDir之前初始化。这可以借鉴设计模式中的Singleton。

//编译单元A内
class FileSystem{...};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}

//编译单元B内
class Directory{...};
Directtory::Directory(params)
{
...
std::size_t disks=tfs().numDisks();//注意这里的形式,与之前不同
}

Director& tempDir()
{
static Directory td;
return td;
}

因为C++保证,函数内的local static对象会在该函数被调用期间首次遇上该对象定义式时被初始化。

好了问题解决了。







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值