Effective C++ ——初始化

初始化,一个老生常谈的话题,你都掌握了吗?
1.初始化和赋值
不是一个概念,记住这点很重要
2.内置类型的初始化
确保在使用之前先初始化,定义时即初始化,避免很多诡异的问题出现。
3.非内置类型的初始化
构造函数负责初始化工作,对于类成员变量,初始化工作发生在进入构造函数之前,在构造函数内部进行的都是赋值动作,不是初始化。
4.使用初始化列表进行初始化

class Animal{};

class Person
{
public:
    Person(const std::string &name, const std::string &addr, const std::list <Animal> &pets, const int &age) :name_(name), addr_(addr), pets_(pets), age_(age)
    {}
private:
    std::string name_;
    std::string addr_;
    std::list <Animal> pets_;
    int age_;
};

说明:
1.使用构造函数中完成初始化工作过程如下:
首先调用name_,addr_,pets_构造函数设定初值,然后立刻对其再进行赋新值,这样构造函数的一切作为因此浪费。
实际调用的是一次构造函数和一次赋值=运算符重载函数一次
2.使用初始化列表完成初始化工作过程如下:
初始化列表中针对各个成员变量的实参被成员变量的构造函数拿去当实参了。
实际调用的是copy构造函数一次
3.效率上来讲,初始化列表更高,另外,对于内置类型,初始化和赋值动作差不多,但为了统一,都在初始化列表中完成初始化是个好的习惯。特别是有时即使是内置类型,但是成员变量是const 或引用类型时,他们需要的是初值,而不能被赋值。
4.C++中,成员变量的初始化顺序固定,即会按照变量声明的顺序完成,所以初始化列表中最好也是按照这个声明的顺序完成初始化。

下面讨论另一个重要的话题,不同编译单元内的non-local static 对象的初始化次序
先了解几个概念
1.static 对象
声明周期是构造出来到程序结束,不同于堆或栈对象。
local static 对象是指函数内部的static 对象,其他就称为non-local static 对象
2. 编译单元
指的是产出单一目标文件的源码,基本上是单一源码文件加上其所包含的头文件
现在,讨论至少两个源码文件,每个文件里面都至少包含一个non-local static对象,如果一个non-local static对象的初始化需要另一个non-local static对象,但问题是,有可能被需要的对象还没有初始化,因为C++ 中,对于不同编译单元内的non-local static 对象的初始化次序并无明确规定。如何解决这个问题?
将non-local static对象转化为local static对象
Person p;//non-local static 对象
替换为函数形式
Person & GetObj()
{
static Person p;//local static 对象
return p;
}
**这种手法成功的基础在于C++ 中,函数内部的local static 对象会在函数被调用期间或首次遇到该对象之定义式时初始化。这样获得的是一个初始化过的对象。
还有一个好处是,如果没有被调用,也不会带来构造和析构成本。**

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值