美文网首页
深入理解C++中的对象和对象引用

深入理解C++中的对象和对象引用

作者: smm987 | 来源:发表于2019-06-14 16:28 被阅读0次

    转载
    有言在先: 返回局部对象和引用, 就像返回局部变量的地址一样, 非常非常危险, 要避免使用。 下面程序中有的地方返回了局部对象的指针, 实际上也是危险的, 但本文先不讨论这个。

    先来看一个入门级的程序:

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
    };
     
    void fun(A a)
    {
     
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun(a);
     
        return 0;
    }
         结果为:
         A constructor
              ---
    

    编译器自动产生的拷贝构造函数得到了调用。

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        ~A()
        {
            cout << "A deconstructor" << endl;
        }
    };
     
    void fun(A a)
    {
     
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun(a);
     
        return 0;
    }
         结果为:
    ---
    A deconstructor
    A deconstructor
    
    

    注意, 有两个对象, 所以有两次析构。
    在第一个程序中, 我们来显式定义一下拷贝构造函数:

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
     
        A(A& a)
        {
            cout << "copy constructor" << endl;
        }
    };
     
    void fun(A a)
    {
     
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun(a);
     
        return 0;
    }
           结果为:
    A constructor
    ---
    copy constructor
    

    可见, 拷贝构造函数确实被调用了
    我们来继续看:

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
     
        A(A& a)
        {
            cout << "copy constructor" << endl;
        }
     
        ~A()
        {
            cout << "A deconstructor" << endl;
        }
     
    };
     
    void fun(A &a)
    {
     
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun(a);
     
        return 0;
    }
          结果为:
    A constructor
    ---
    A deconstructor
    

    可见, 没有对象的拷贝。 这样, 在fun函数中, 就省略了拷贝的过程, 而是直接引用a. 节省时间, 节省空间, 真好

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
     
        A(A& a)
        {
            cout << "copy constructor" << endl;
        }
     
        ~A()
        {
            cout << "A deconstructor" << endl;
        }
     
    };
     
    A fun()
    {
        A a;
        cout << "------" << endl;
        return a;
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun();
     
        return 0;
    }
          结果为:
    A constructor
    ---
    A constructor
    ------
    copy constructor
    A deconstructor
    A deconstructor
    A deconstructor
    
    

    继续看:

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
     
        A(A& a)
        {
            cout << "copy constructor" << endl;
        }
     
        ~A()
        {
            cout << "A deconstructor" << endl;
        }
     
    };
     
    A& fun()
    {
        A a;
        cout << "------" << endl;
        return a; // 翻译局部对象的引用, 危险。
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun();
     
        return 0;
    }
          结果为:
    A constructor
    ---
    A constructor
    ------
    A deconstructor
    A deconstructor
    

    看吧, 在函数返回的时候, 是返回引用的, 这样, 又少了一次拷贝。
    继续看一个稍微复杂一点的:

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
     
        A(A& a)
        {
            cout << "copy constructor" << endl;
        }
     
        ~A()
        {
            cout << "A deconstructor" << endl;
        }
     
    };
     
    A fun(A a)
    {
        A aa;
        cout << "------" << endl;
        return aa;
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun(a);
     
        return 0;
    }
          结果:
    A constructor
    ---
    copy constructor
    A constructor
    ------
    copy constructor
    A deconstructor
    A deconstructor
    A deconstructor
    A deconstructor
    

    对上面程序进行优化:

    #include <iostream>
    using namespace std;
     
    class A
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
     
        A(A& a)
        {
            cout << "copy constructor" << endl;
        }
     
        ~A()
        {
            cout << "A deconstructor" << endl;
        }
     
    };
     
    A& fun(A& a)
    {
        A aa;
        cout << "------" << endl;
        return aa;  // 返回局部对象的引用, 危险。
    }
     
    int main()
    {
        A a;
        cout << "---" << endl;
        fun(a);
     
        return 0;
    }
          结果为:
    A constructor
    ---
    A constructor
    ------
    A deconstructor
    A deconstructor
    

    可见, 对象引用在C++中确实有很大的好处。比传对象快捷高效, 比指针更优美。

    相关文章

      网友评论

          本文标题:深入理解C++中的对象和对象引用

          本文链接:https://www.haomeiwen.com/subject/wuepfctx.html