码迷,mamicode.com
首页 > 编程语言 > 详细

c++返回对象值

时间:2015-06-05 06:23:43      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

  首先看一道面试题如下:

A test()
{
    A a1 (2);
    std::cout << &a1 << std::endl;
    return a1;
}
A a2 = test();

  对于以上代码,大概解释下过程。

  test()函数中构造a1对象,当返回时,构造临时对象,并使用a进行拷贝构造。当A a2 = test()是,a2使用临时对象进行拷贝构造,也就是一共有2次拷贝构造,1次构造函数;

  但是当使用代码测试的时候,结果和想象的不一样。

#include <iostream>

class A
{
public:
    A(int i)
        :a(i)
    {
        std::cout << "construct " << i <<std::endl;
    }

    ~A()
    {
        std::cout << "des constrcut " << a << std::endl;
    }

    A(const A& a)
    {
        std::cout << "copy constrcut "  << std::endl;
        this->a = a.a;
    }

    A& operator=(const A& b)
    {
        std::cout << "assign operation " << std::endl;
        this->a  = b.a;
        return *this;
    }

public:
    int a;
};

A test()
{
    A a (2);
    std::cout << &a << std::endl;
    return a;
}

int main()
{

    A a = test();
    std::cout << &a << std::endl;
    return 0;
}

  g++ test.cpp -o test ,运行时,输入如下。 技术分享

技术分享

  结果发现,构造函数只执行了一次,并且没有执行拷贝构造函数,并且test()函数体内的对象地址和main()中的对象地址竟然相同。

  查询后发现,原来编译器会自动执行值返回优化,即RVO。RVO会将a对象的地址传到test函数中,test函数直接修改a对象,避免了拷贝操作。维基百科有详细介绍:http://en.wikipedia.org/wiki/Return_value_optimization

  最后,gnu的编译器可以通过-fno-elide-constructors 选项关闭RVO。g++ test.cpp  -fno-elide-constructors  -o test。 运行结果如下。

技术分享

   大概过程如下:

      test()函数对象a调用构造函数,返回时候临时对象拷贝构造,然后函数内对象析构。

      然后main()函数对象a拷贝构造临时对象,然后析构临时对象。

      最后析构对象a。

  

c++返回对象值

标签:

原文地址:http://www.cnblogs.com/jerett/p/4553620.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!