zoukankan      html  css  js  c++  java
  • 类中成员变量的初始化顺序

    对于类中的成员变量的初始化要注意:

    考虑:

    #include<iostream>
    using namespace std;
    
    class A
    {
    private:
        int n1;
        int n2;
        
    public:
    
        A():n2(0),n1(n2+2){} 
        
        void Print(){
            cout << "n1:" << n1 << ", n2: " << n2 <<endl;  
        }
    };
    
    int main()
    {
    
        A a;
        a.Print();
    
        getchar();
        return 1;
    }

    输出以上结果的时候,以为是n1:2,n2:0吗

    错了!

    #include<iostream>
    using namespace std;
    
    class A
    {
    private:
        int n1;
        int n2;
        
    public:
    
        //A():n2(0),n1(n2+2){} //n1:-858993458, n2: 0
        //A():n1(n2+2),n2(0){}    //n1:-858993458, n2: 0
        //A():n1(0),n2(n1+2){}//n1:0, n2: 2
        A():n2(n1+2),n1(0){}//n1:0, n2: 2
    
        void Print(){
            cout << "n1:" << n1 << ", n2: " << n2 <<endl;  
        }
    };
    
    int main()
    {
    
        A a;
        a.Print();
    
        getchar();
        return 1;
    }

    尝试运行以上的例子,可以发现,在用T():name(),name2():{}的形式进行初始化的时候,初始化的顺序是与类中本来类的变量位置的顺序有关,与T():name(),name2():{}的形式中变量名的顺序无关。

    为什么要这样做?为什么C++不按初始化列表的顺序来初始化成员变量呢? 

    因为我们知道初始化的顺序应该与析构的顺序相反,也就是说,如果有两个成员变量 A 和 B ,初始化顺序为 A -> B ,那么在这个类被析构时,应该先析构 B 再析构 A。而对一个类来说 constructor 可能有多个,初始化列表也会有多个,所以如果我们要按初始化列表的顺序来进行初始化,那么我们就得记住这个顺序,以便在析构时决定析构的顺序。所以C++就选择了简单的点的方法,按成员变量出现的顺序来初始化。

    总结:既然如此,我们在写初始化列表时最好按成员变量出现的顺序来写,这样不容易出现混淆。

    参考:effective C++, http://blog.sinzy.net/hjk41/entry/7998

  • 相关阅读:
    CSS——清除浮动
    .net 多线程之线程取消
    .net 多线程临时变量
    NPOI helper
    添加学员存储过程
    SQL-sqlHelper001
    ado.net 中事务的使用
    T-SQL 事务2
    T-SQL 事务
    T-SQL 带参数存储过程
  • 原文地址:https://www.cnblogs.com/huhuuu/p/3484875.html
Copyright © 2011-2022 走看看