关于C++的构造函数的几点注意

来源:互联网 发布:英文语音识别软件 编辑:程序博客网 时间:2024/04/28 09:32

1. 构造函数初始化式于显示赋值的区别

     与任何其他函数一样,构造函数具有名字、形参表和函数体。与其他函数不同的是,构造函数也可以包含一个构造函数初始化列表。
a)Sales_item::Sales_item(const string &book): isbn(book), units_sold(0), revenue(0.0) { }b)Sales_item::Sales_item(const string &book){isbn = book;units_sold = 0;revenue = 0.0;}
        合理的使用构造函数的初始化式是非常重要的,b)类 Sales_item 的成员赋值,但没有进行显式初始化。不管是否有显式的初始化式,在执行构造函数之前,要初始化isbn 成员。这个构造函数隐式使用默认的 string 构造函数来初始化 isbn。执行构造函数的函数体时,isbn 成员已经有值了。该值被构造函数函数体中的赋值所覆盖。   
       从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。计算阶段由构造函数函数体中的所有语句组成。
       不管成员是否在构造函数初始化列表中显式初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。两个版本具有同样的效果:无论是在构造函数初始化列表中初始化成员,还是在构造函数函数体中对它们赋值,最终结果是相同的。构造函数执行结束后,三个数据成员保存同样的值。不同之外在于,使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数函数体中对数据成员赋值。这个区别的重要性取决于数据成员的类型。

2.必须使用初始化列表的情况

        有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数函数体中对它们赋值不起作用。没有默认构造函数的类类型的成员,以及 const 或引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。
        因为内置类型的成员不进行隐式初始化,所以对这些成员是进行初始化还是赋值似乎都无关紧要。除了两个例外(const 和引用),对非类类型的数据成员进行赋值或使用初始化式在结果和性能上都是等价的。
       例如,下面的构造函数是错误的:
     class ConstRef {     public:         ConstRef(int ii);     private:         int i;         const int ci;         int &ri;     };     // no explicit constructor initializer: error ri is uninitialized     ConstRef::ConstRef(int ii)     {              // assignments:          i = ii;   // ok          ci = ii;  // error: cannot assign to a const          ri = i;   // assigns to ri which was not bound to an object     }// ok: explicitly initialize reference and const members     ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }
      在许多类中,初始化和赋值严格来讲都是低效率的:数据成员可能已经被直接初始化了,还要对它进行初始化和赋值。比较率问题更重要的是,某些数据成员必须要初始化,这是一个事实。




原创粉丝点击