zoukankan      html  css  js  c++  java
  • 成员初始化表

    使用初始化表和在构造函数内使用数据成员的赋值之间有什么区别:

    inline Account::
    Account( const char *name, double opening_bal )
     : _name( name ), _balance( opening_bal )
    {
     _acct_nmbr = get_unique_acct_nmbr();

    }

    inline Account::
    Account( const char *name, double opening_bal )
    {
     _name = name;
     _balance = opening_bal;
     _acct_nmbr = get_unique_acct_nmbr();

    两种实现的最终结果是一样的。区别是成员初始化表只提供该类数据成员的初始化。在构造函数体内对数据成员设置值是一个赋值操作。区别的重要性取决于数据成员的类型

    我们可以认为构造函数执行过程分为两个阶段:1.隐式或显式初始化阶段 2.一般的计算阶段。

    计算阶段由构造函数体内的所有语句组成。在计算阶段中,数据成员的设置被认为是赋值,而不是初始化。

    初始化阶段可以是显式的或隐式的,取决于是否存在成员初始化表,隐式初始化阶段按照声明的顺序依次调用所有基类的缺省构造函数,然后是所有成员对象的缺省构造函数。

    如下代码:

    inline Account::
    Account()
    {
     _name = "";
     _balance = 0.0;
     _acct_nmbr = 0;
    }

    则初始化阶段是隐式的,在构造函数体被执行之前,先调用与_name 相关联的缺省 string构造函数;这意味着把空串赋给_name 的赋值操作是没有必要的。

    对于类对象,在初始化和赋值之间的区别是巨大的。成员类对象应该总是在成员初始化表中被初始化,而不是在构造函数体内被赋值。

    缺省 Account 构造函数的更正确的实现如下:

    inline Account::
    Account() : _name( string() )
    {
     _balance = 0.0;
     _acct_nmbr = 0;
    }

    我们已经去掉了在构造函数体内不必要的对_name 的赋值;但是,对于缺省构造函数的显式调用也是不必要的,下面是更紧凑但却等价的实现:

    inline Account::
    Account()
    {
     _balance = 0.0;
     _acct_nmbr = 0;

    对于非类数据成员的初始化或赋值,除了两个例外,两者在结果和性能上都是等价的;即 更受欢迎的实现是用成员切始化表。

    // 更受欢迎的初始化风格
    inline Account::
    Account() : _balanae( 0.0 ), _acct_nmbr( 0 )
     { }

    两个例外是指任何类型的 const 和引用数据成员

    const 和引用数据成员也必须是在成员初始化表中被初始化,否则 就会产生编译时刻错误。

    例如 :下列构造函数的实现将导致编译时刻错误  

    class ConstRef {
    public:
     ConstRef( int ii );
     
    private:
     int i;
     const int ci;
     int &ri;
    };
     
    ConstRef::
    ConstRef( int ii )
    { // 赋值
     i = ii; // ok
     ci = ii; // 错误: 不能给一个 const 赋值
     ri = i; // 错误  ri 没有被初始化
    }

    当构造函数体开始执行时,所有const 和引用的初始化必须都已经发生

    因此,只有将它们在成员初始化表中指定这才有可能。正确的实现如下 

    // ok: 初始化引用和 const
    ConstRef::
    ConstRef( int ii )
     : ci( ii ), ri( ii )
     { i = ii; }

    每个成员在成员初始化表中只能出现一次,初始化的顺序不是由名字在初始化表中的顺序决定,而是由成员在类中被声明的顺序决定的。


  • 相关阅读:
    拷贝某文件至某位置
    Java对象的序列化和反序列
    常见的RuntimeException异常有哪些
    array数组增删元素
    失眠怎么办
    构造函数和函数区别(关键的new操作符)
    匿名函数递归(arguments.callee)和命名函数递归
    localeCompare方法在chrome浏览器取值问题
    random()方法
    iframe 父子页面之间取值
  • 原文地址:https://www.cnblogs.com/lidan/p/2239493.html
Copyright © 2011-2022 走看看