c++ - 当使用 'auto' 时,从函数返回引用是否会导致创建新的临时对象?

标签 c++ c++11 reference auto

我编写了以下代码,其中函数返回对成员的引用。在对函数的 2 次不同调用期间,返回值以 2 种方式存储:

  1. 自动引用用于存储返回值。正如我正确假设的那样,返回引用的对象的地址和存储返回值的自动引用的地址是相同的,从输出中可以明显看出。
  2. 'auto'用于存放返回值。我假设,自动变量应该导致在堆栈上创建一个新对象,该对象包含函数返回引用的对象值的拷贝。我可以看到 auto 和实际对象的地址确实不同。但是,我没有看到为使用 auto 创建的对象调用构造函数。在这种情况下确实创建了一个对象吗?

//代码

    #include <iostream>
    using namespace std;

    class c1 {
    private:
        int i;

    public:
        c1() {
            cout << "c1()" << endl;
            i = 10;
        }

    };

    class c2 {
    private:
        c1 mc1;

    public:
        c2() {
            cout << "c2()" << endl;
        }

        c1& getmc1() {
            cout << "address of mc1 : " << &mc1 << endl;
            return mc1;
        }
    };

    int main() {
        c2 c;
        auto& c1_1 = c.getmc1();
        cout << "address of c1_1 : " << &c1_1 << endl;

        c2 c_2;
        auto c1_2 = c_2.getmc1();
        cout << "address of c1_1 : " << &c1_1 << endl;

        return 0;
    }


//Output
c1()
c2()
address of mc1 : 00AFF82C   --> Same as below address, expected
address of c1_1 : 00AFF82C
c1()
c2()
address of mc1 : 00AFF814  --> Different from below address, expected
address of c1_1 : 00AFF82C --> why c1() constructor is not invoked ?

编辑

@NathanOliver,@Tali,

感谢您指出有关复制构造器的问题。我添加了一个,我可以看到正确的输出。我是 C++ 的初学者。我错过了编译器生成隐式复制构造函数的要点。

下面是更新后的程序。

#include <iostream>
using namespace std;

class c1 {
private:
    int i;

public:
    c1() {
        cout << "c1()" << endl;
        i = 10;
    }

    c1(c1 &c) {
        cout << "c1(c1 &c)" << endl;
        i = c.i;
    }

};

class c2 {
private:
    c1 mc1;

public:
    c2() {
        cout << "c2()" << endl;
    }

    c1& getmc1() {
        cout << "address of mc1 : " << &mc1 << endl;
        return mc1;
    }
};

int main() {
    // your code goes here
    c2 c;
    auto& c1_1 = c.getmc1();
    cout << "address of c1_1 : " << &c1_1 << endl;

    c2 c_2;
    auto c1_2 = c_2.getmc1();
    cout << "address of c1_1 : " << &c1_2 << endl;

    return 0;
}

输出:

c1()
c2()
address of mc1 : 010FFE18
address of c1_1 : 010FFE18
c1()
c2()
address of mc1 : 010FFE00
c1(c1 &c)
address of c1_1 : 010FFDF4

最佳答案

是的,新对象已构建,但未使用您的c1::c1()。 对象的此类拷贝是使用复制构造函数 c1::c1(const c1 &) 完成的。

在您的示例中,您没有提供复制构造函数,因此编译器将隐式生成一个。

关于c++ - 当使用 'auto' 时,从函数返回引用是否会导致创建新的临时对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42654259/

相关文章:

c++ - 如何在不使用 C++ 中的任何库的情况下检测图像中的对象?

c++ - 使用 std::tie 进行类似 golang 的错误处理同时返回结果是否有缺点? (C++11)

c# - 引用的程序集中缺少 namespace

c++ - 将 multimap<Key,Value> 转换为 vector <vector<Value>>

c++ - 如何使用依赖于符号调试的参数定义函数?

c# - XAML 中的命名空间错误中不存在类

python - Python 可变对象中的引用与赋值

c++ - boost 正则表达式 :switching between ascii and unicode

c++ - 在集合中查找最近的元素

c++ - 在 typedef 结构体上使用 sizeof 运算符