c++返回对象值

  首先看一道面试题如下:

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。

  

时间: 2024-09-29 22:07:45

c++返回对象值的相关文章

SpringMVC中通过@ResponseBody返回对象,Js中调用@ResponseBody返回值,统计剩余评论字数的js,@RequestParam默认值,@PathVariable的用法

1.SpringMVC中通过@ResponseBody返回对象,作为JQuery中的ajax返回值 package com.kuman.cartoon.controller; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.filefilter.FalseFileFilter; import org.slf4j.Logger; import org.s

C++基础知识(八)---函数返回值(返回值,返回指针,返回对象,返回引用)---引用---复制构造函数(拷贝构造函数)

一.函数返回值 1.返回值: int test () { int a=1; return a; } 返回值时最简单的方式,它的操作主要在栈上,变量a在函数结束后会删除,为了返回a的值,系统会在内部建立一个临时变量保存a的值,以返回给调用该函数的表达式,调用结束后变量便不再存在.如果a是简单地数据类型也无所谓,不是很占用内存,如果a是大的自定义类型的数据,那么对a的复制将会占用比较大的内存.函数返回值是右值,不能进行运算符操作. 2.返回指针: int *test2() { int *b=new

【笔记】关于jq $.ajax 函数 success回调函数不能赋正确值或返回正确值的问题

最近在一个项目里面打算实现如下功能: 当我注册账号的时候当输入账号完毕后输入框失焦时执行一个 ajax 请求,验证账号是否被注册,并未这个输入框的 isCorrect属性赋值,如果没有被注册 isCorrect属性值为"true",否则为 "false".代码如下: ajax: function(obj){ /* { elem: //验证的元素, hintsContent: //提示框元素, errorColor: //错误时显示的颜色, url: //后台处理页地

HQL查询——查询返回对象类型分析

关于HQL查询,我们可以结合hibernate的API文档,重点围绕org.hibernate.Query接口,分析其方法,此接口的实例对象是通过通过session.对象的creatQuery(String hql)方法得到的.我这里要分析HQL的select子句,当然要想深入HQL查询,我们就必须了解hibernate缓存的知识. 一.选择--Select子句查询返回对象的讨论 为什么只说Select子句,因为我们使用的hibernate框架是基于java语言环境下进行开发的,也就是说hibe

条款21:必须返回对象时,别妄想返回其reference

条款21:必须返回对象时,别妄想返回其reference 引用只是对象的一种别名当使用引用的时候,请确认他的另一个身份在哪? class Rational { public: Rational(int x, int y) : m_x(x), m_y(y){} //返回const是属于类型保护,friend修饰,以后条款详说 friend const Rational operator + (const Rational &lhs, const Rational &rhs) { Ration

Effective C++:条款21:必须返回对象时别妄想返回其reference

(一) 一定要避免传递一些references去指向其实并不存在的对象. 看下面这个类: class Rational { public: Rational(int numerator = 0, int denominator = 1); private: int n, d; friend const Rational operator*(const Rational& lhs, const Rational& rhs); }; 这个函数不能返回引用, (二)在stack中分配local对

javascript 对象初探(二)--- 返回对象的函数

除了使用new操作符调用构造函数以外,我们也可以抛开new操作符,只用一般函数来创建对象,这样就能执行某些预备工作,并已对象为返回值的函数.. function her(){ return { name : 'Jon' }; } 然后我们调用her()来生成对象: var a = her(); a.name; // Jonconsole.log(a.constructor);// function Object(){} 实际上构造函数也是可以返回对象的,只不过this的值使用上将会有所不同. f

Item 21:需要返回对象时,不要返回引用 Effective C++笔记

Item 21: Don't try to return a reference when you must return an object Item 20中提到,多数情况下传引用比传值更好.追求这一点是好的,但千万别返回空的引用或指针. 一个典型的场景如下: class Rational{ int n, d; public: Raitonal(int numerator=0, int denominator=1); }; // 返回值为什么是const请参考Item 3 friend con

[坑爹]Xcode7.3 解决调试窗口对象值为nil的问题

你是否遭受过一个经历 就是在调试网络请求的时候 在回调block内打下一个断点来查看返回对象的值得时候  发现调试窗口右边显示的responseObject = nil, 你是否怀疑过这是xcode的BUG, 我以前也曾遇到这个问题并且饱受折磨, 今天无意间把Release改成了Debug, 奇迹出现了, 调试窗口右侧能显示出对象的值了, 不需要NSLog也能看到了, 虽然这是个很白痴的问题, 不过我相信有人跟我一样很无奈, 希望能帮助他们.