• [effictive c++] 条款04 确定对象被使用前已被初始化


    成员初始化

    在c和c++ 中,使用为初始化的类型经常会引发不可预料的错误,从而使得我们要花费巨大的时间用于调试查找问题,所以确定对象被使用前已被初始化是个非常好的习惯。

    永远在使用之前对对象进行初始化。对于无不论什么成员的内置类型,你必须手工完毕初始化操作。由于c++不保证初始化他们。


    内置类型意外的其它东西,初始化责任落在构造函数身上。但要注意区分构造函数中的变量是赋值还是初始化。

    举个样例

    class PhoneNumber{...};
    class ABEntry{
    public:
    	ABEntry(const std::string &name, const strd::string& address, const std::list<PhoneNumber>& phones);
    private:
    	std::string theName;
    	std::string theAddress;
    	std::list<PhoneNumber> thePhones;
    	int numTimesConsulted;
    
    };
    
    ABEntry::ABEntryconst std::string &name, const strd::string& address, const std::list<PhoneNumber>& phones)
    {
    	theName = name;		//这些都是赋值
    	theAddress = address;		//而非初始化
    	thePhones = phones;                 //注意区分
    	numTimesConsulted = 0;
    }

    上述构造函数中的变量是赋值。而非初始化。这么做能够使得变量是你期望的数值。但这并非一个好的做法。那么怎样推断是赋值和初始化呢?c++规定,变量的初始化应在进入构造函数体之前。所以上面的构造函数先对各个变量运行了default初始化,然后又对变量进行了赋值。

    (ps:内置类型 变量不保证一定在赋值动作前获得初指

    ABEntry构造函数一个极好的写法是用member initialization list(成员初值列表),详细例如以下:

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

    这个版本号的构造函数是在进入构造函数之前进行了初始化。构造函数体内则无需在进行赋值。这样就省去了赋值操作的开销。效率通常更高。

    为什么我这里用"通常"更高? 由于内置类型如numTimesConsulted ,其初始化和赋值的代价同样,为了一致性。通常将其也用成员初值列表初始化。

    有些情况下,即使变量属于内置类型也一定要用成员初值列表,比如成员变量是const或references,他们不能被赋值。仅仅能被初始化。


    classes拥有多个构造函数。且每一个构造函数都有自己的成员初值列表时怎么办?

    假设classes存在很多成员变量或base classes , 会导致很多反复的初值列,同一时候也加重了开发者的工作。

    这样的情况下能够在初值列中遗漏那些“赋值像初始化一样好”的成员变量,改为赋值操作,并将赋值操作移往某个函数内(一般是private 函数),供全部构造函数使用。

    这样就能够省去非常多无谓的反复劳动。


    成员初始化次序

    以下我们来说一说成员初始化的次序。c++中成员初始化的次序总是同样的:base classes早于derived classes被初始化。class成员总是依照声明次序进行初始化。所以为了避免不必要的麻烦,成员初值列的顺序最好与声明顺序一致。


    总结

    • 为内置对象进行手工初始化。由于c++不保证初始化他们
    • 构造函数使用成员初值列,而不要在构造函数本体内使用赋值操作,初始列列出变量的顺序应该和他们在class中生命顺序一致。

    參考自《effictive c++ 》

  • 相关阅读:
    [ACM_模拟] ZJUT 1155 爱乐大街的门牌号 (规律 长为n的含k个逆序数的最小字典序)
    [ACM_搜索] ZOJ 1103 || POJ 2415 Hike on a Graph (带条件移动3盘子到同一位置的最少步数 广搜)
    [ACM_动态规划] POJ 1050 To the Max ( 动态规划 二维 最大连续和 最大子矩阵)
    [ACM_搜索] POJ 1096 Space Station Shielding (搜索 + 洪泛算法Flood_Fill)
    [JAVA] java_实例 获得系统字体
    [JAVA] java仿windows 字体设置选项卡
    [JAVA] 一个可以编辑、编译、运行Java简单文件的记事本java实现
    [ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)
    JS的数组相关知识
    JS的join方法
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7346467.html
Copyright © 2020-2023  润新知