返回值为对象的情况

g++ -fno-elide-constructors tmpObj.cpp -o tp

/*
 * tmpObj.cpp
 *
 *  Created on: 2021年6月1日
 *      Author:
 */

#include <iostream>
using namespace std;

class A {
public:
    int m_k;
    int m_t;
    A() {
            cout << "A() construct...." << endl;
            m_k = 0;
            m_t = 0;
        }
    A(int k, int t) :m_k(k), m_t(t) {
        cout << "param construct...." << endl;
    }
    ~A() {
        cout << "destruct...." << endl;
    }
    A(const A &a) {
        cout << "copy construct..." << endl;
    }
};

//  如果函数返回值是一个对象,要考虑return语句的效率
A getObj() {
        /************** 返回本地对象 ****************/
              /* 以下这种写法实际上执行了三步:
                  1. 构造本地对象a
                  2. 调用拷贝构造,将本地对象a拷贝到外部存储器
                  3. 调用析构函数析构本地对象a
              */
         /******************************************/
    A a(3, 4);
    return a;
}

//  如果函数返回值是一个对象,要考虑return语句的效率
A getDirectObj() {
    /***********  直接返回临时对象  *************/
    // 编译器直接把临时对象创建并初始化在外部
    // 存储单元(主调函数的栈帧上)中,省去了拷
    // 贝和析构的花费,提高了效率
    /*****************************************/
    return A(3, 4);
}

class B{
public:
    int val;
public:
    B(int val):val(val) {}
};

int main() {
//    A a0 = getObj();   //  外部存储单元
//    A a = getDirectObj();

//    param construct....
//    copy construct...
//    destruct....
//    destruct....
//    getObj();   //  外部存储单元
    getDirectObj();
//    B& b1 = B(3); // 报错
    const B& b2= B(3); // 正确
    return 0;
}

 

因为对于右值来说,修改它的值是无意义的,所以才不能把一个左值引用绑定到一个右值上,但是C++允许把一个const引用绑定到一个右值上

 

#include <iostream>

using namespace std;

int add(int &num1, int &num2) {
    return num1 + num2;
}

int main() {
    cout << add(3, 3) << endl;  //这里3是右值,不能绑定到左值引用上
    return 0;
}
//报错:error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'

如果我们不需要改变实参的值,又需要用引用传递参数,建议要把引用定义为常量引用

#include <iostream>

using namespace std;

int add(const int &num1, const int &num2) {
    return num1 + num2;
}

int main() {
    cout << add(3, 3) << endl; 
    return 0;
}

 

posted @   星辰大海浩瀚宇宙呀  阅读(5)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示