首页 > 解决方案 > 为什么当我尝试返回引用时我的对象仍然被复制

问题描述

class Obj {
public:
    Obj(int aa, int bb): a(aa), b(bb) {}
    Obj(const Obj& o) {a = o.a; b = o.b;std::cout << "copying" << std::endl;}
    Obj(Obj&& o) {a = o.a; b = o.b;std::cout << "moving" << std::endl;}
    int a;
    int b;
};
const Obj& Min(const Obj &o1, const Obj &o2) {
    if (o1.a > o2.a) {
        return o1;
    } else {
        return o2;
    }
}
int main() {
    using namespace std;

    auto o1 = Obj(1,1);
    auto o2 = Obj(2,2);
    auto res = Min(o1, o2);

    cout << res.a << endl;
    res.a = 100;
    cout << o1.a << endl;
    cout << o2.a << endl;

    return 0;
}

程序仍然打印一个字copying,表示复制构造函数已激活。那么构造函数在哪里调用呢?为什么函数不返回对的引用,o1从而修改 的值res也会改变 的值o1

标签: c++c++11pass-by-referenceautolvalue

解决方案


副本在语句中完成:

auto res = Min(o1, o2);

Min()返回类型是const Obj&. 以上auto将推导出为Obj,而不是const Obj&(即,res类型将是Obj)。res是一个对象,通过复制构造函数(即Obj::Obj(const Obj&))进行初始化,因此发生了复制构造。

如果你改为写:

auto& res = Min(o1, o2)

res将是类型const Obj&,并且不会在那里进行复制构造,因为res将是引用,而不是对象。


推荐阅读