none
请教一个返回值和拷贝构造函数的问题 RRS feed

  • 问题

  • 一个类A,实现了构造函数,拷贝构造函数,赋值操作符,析构函数
    一个函数返回这个类对象:
    A getA()
    {
        A a;
        return a;
    }

    另一个函数这样调用getA
    void fun()
    {
       A a = getA(); //或者 A a(getA());
    }

    这样只执行一遍构造函数和析构函数

    但是如果这样写 getA 函数的话
    A& getA()
    {
        A a;
        return a;
    }
    返回引用,就可以执行构造函数,拷贝构造函数,两遍析构函数

    请讲解一下这是怎么回事,什么原理,谢谢


    如果没有执行拷贝构造函数,析构函数,那fun那个函数里的 a 对象是从哪来的?总归得有个来头吧,getA函数里的A的对象释放了,但是以值传递的方式返回给了fun 函数的a 对象,应该执行拷贝构造函数呀,fun 函数结束时也应该执行a的析构函数呀,奇怪


    还有,如果在fun 函数里:

    A a;
    a = getA();

    这样就会调用赋值运算符,并且执行两遍析构函数,

    怎么样,这个题目有意思吧?谁能解释一下?

    2009年2月13日 8:16

答案

  • 第一种情况应该是编译器而定,是编译器的自定义行为。好像这类优化并没有加入到标准之中。
    第二种情况应该是正确的,先执行构造然后对象被析构,在函数返回的时候执行拷贝但这是是一个trail的拷贝。最后主函数退出的时候执行析构。
    第三种情况也没有问题,唯一的不同是主函数的a对象已经创建出来了。

    关于此类问题在《深入探索C++对象模型》一书中有较稳详细的介绍楼主可以参考。
    2009年2月13日 8:49
    版主
  •  在这种情况下getA();函数有可能已经被完全优化掉了。你看看汇编,到底如何优化要看各种编译器的行为。
    2009年2月13日 9:21
    版主

全部回复

  • 第一种情况应该是编译器而定,是编译器的自定义行为。好像这类优化并没有加入到标准之中。
    第二种情况应该是正确的,先执行构造然后对象被析构,在函数返回的时候执行拷贝但这是是一个trail的拷贝。最后主函数退出的时候执行析构。
    第三种情况也没有问题,唯一的不同是主函数的a对象已经创建出来了。

    关于此类问题在《深入探索C++对象模型》一书中有较稳详细的介绍楼主可以参考。
    2009年2月13日 8:49
    版主
  • 这样的话,对象遇到右括号栈反解就不绝对了,

    比如:
    A a = getA();
    getA() 函数里定义的a 遇到函数结束时的右括号应该栈反解,调用a的析构函数,但是这种情况下没有,
    而是在外层函数退出时才析构。

    并且经过试验,发现getA()函数里的a 的地址和返回到外面的a 的地址完全一样,是同一个对象,但是这里并不是引用或者指针,应该进行值拷贝呀
    2009年2月13日 8:55
  •  在这种情况下getA();函数有可能已经被完全优化掉了。你看看汇编,到底如何优化要看各种编译器的行为。
    2009年2月13日 9:21
    版主
  • 哦,原来是这样,好的,谢谢
    2009年2月13日 9:26