zoukankan      html  css  js  c++  java
  • 宋体、构造函数浅出C++对象模型——理解构造函数、析构函数执行顺序by小雨

    PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,码代几天不写就忘。目前又不当COO,还是得用心记码代哦!

       

        本文重要说明象对建创时结构函数的执行序次,象对成员的初始化序次;象对毁销时析构函数的执行序次,象对成员的毁销序次。

      

        “象对的结构从类层次的最根处开始,在每一层中,首先调用基类的结构函数,然后调用成员象对的结构函数。析构则格严按照与结构相反的序次执行,该序次是独一的,否则译编器将没法动自执行析构程过。

        一个趣有的现象是,成员象对初始化的序次全完不受它们在初始化表中序次的影响, 只由成员象对在类中声明的序次决议。这是因为类的声明是独一的,而类的结构函数可以有多个,因此会有多个不同序次的初始化表。如果成员象对按照初始化表的序次行进结构,这将致使析构函数没法到得独一的逆序。”(引用自References[1]

         

        从这里看,每种言语特性的存在必有其因原,习学这些特性就是懂得这些特性存在的因原。

        面下的一段码代是对面下这段话的说明,其中有4个类Foo, Bar, Base, Derived,它们的结构函数、拷贝结构函数、析构函数都有息信输出。

    #include <iostream>
    using namespace std;
    
    class Foo
    {
    public:
            Foo() { cout << "Foo constructor" << endl; }
            Foo(const Foo &foo) { cout << "Foo copy constructor" << endl; }
            ~Foo() { cout << "Foo deconstructor" << endl; }
    };
    
    class Bar
    {
    public:
            Bar() { cout << "Bar constructor" << endl; }
            Bar(const Bar &bar) { cout << "Bar copy constructor" << endl; }
            ~Bar() { cout << "Bar deconstructor" << endl; }
    };
    
    class Base
    {
    public:
            Base() { cout << "Base constructor" << endl; }
            ~Base() { cout << "Base deconstructor" << endl; }
    };
    
    class Derived : public Base
    {
    public:
            Derived() { cout << "Derived constructor without arguments" << endl; }
            Derived(const Foo &foo, const Bar &bar);
            Derived(const Bar &bar, const Foo &foo);
            ~Derived() { cout << "Derived deconstructor" << endl; }
    
    private:
            Foo m_foo;
            Bar m_bar;
    };
    
    Derived::Derived(const Foo &foo, const Bar &bar) :
            m_foo(foo),
            m_bar(bar)
    {
            cout << "Derived constructor with argument[Foo foo, Bar bar] passed by references" << endl;
    }
    
    Derived::Derived(const Bar &bar, const Foo &foo) :
            m_bar(bar),
            m_foo(foo)
    {
            cout << "Derived constructor with argument[Bar bar, Foo foo] passed by references" << endl;
    }
    
    int main (int argc, char** argv)
    {
            Foo foo;
            Bar bar;
    
            cout << "test case 1:" << endl;
            Derived deri_1;  //  (1)
    
            cout << "test case 2:" << endl;
            Derived deri_2(foo, bar);   //  (2)
    
            cout << "test case 3:" << endl;
            Derived deri_3(bar, foo);   //  (3)
    
            cout << "test case end" << endl;
    
            return 0;
    }

        执行结果是:

        

        

        打印出的息信可分为几部份:

        (1) 建创象对foobar ,执行Foo,Bar的结构函数

        (2) Test Case 1:建创象对deri_1,首先执行基类Base的结构函数,其次执行成员m_foo,m_bar的结构函数来结构成员,最后调用自身的结构函数(无参数)

        (3) Test Case 2:建创象对deri_2,调用序次与case 1序次同相。

        (4) Test Case 3:建创象对 deri_3,调用序次与case 1序次同相。注意到deri_2,deri_3的建创执行的是不同的Derived结构函数,虽然结构函数参数的序次不同,但是结构成员的序次是同相的。

        (5) 毁销象对deri_3,deri_2,deri_1,析构函数执行序次同相,与结构象对的序次相反。C++标准划定以象对声明相反的序次毁销这些象对。

        (6) 毁销象对bar,foo

        

        译编运行环境:

    $ uname -a
    Linux localhost.localdomain 2.6.18-308.el5 #1 SMP Fri Jan 27 17:17:51 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
    
    $ g++ --version
    g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)

        References:

        [1]高质量C++编程指南http://oss.org.cn/man/develop/c&c++/c/c.htm

        [2] http://stackoverflow.com/q/15948381/1145750

        转载本文请注明作者和出处http://garyelephant.me,请勿用于任何商业用途!

        Author: Gary Gao 存眷互联网、动自化、件软团队 

    文章结束给大家分享下程序员的一些笑话语录: 女人篇
      有的女人就是Windows虽然很优秀,但是安全隐患太大。
      有的女人就是MFC她条件很好,然而不是谁都能玩的起。
      有的女人就是C#长的很漂亮,但是家务活不行。
      有的女人就是C++,她会默默的为你做很多的事情。
      有的女人就是汇编虽然很麻烦,但是有的时候还得求它。
      有的女人就是SQL,她会为你的发展带来莫大的帮助。

  • 相关阅读:
    直方图均衡
    k-means聚类方法
    核函数
    支持向量机(SVM)
    函数的定义和调用
    ES5新增方法
    继承
    构造函数和原型
    面向对象版tab 栏切换
    ES6中的对象与类
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3026161.html
Copyright © 2011-2022 走看看