按值返回不会创建新对象

dev*_*ull 6 c++

我想尝试一下我读到的关于在C++中按值返回的内容(它与在新对象中创建时传递值相同)我有这样的代码:

#include <iostream>

using namespace std;

class Kar{

public:
    int n;
    static int no;

    Kar(){
        n = ++Kar::no;
        cout << "Creating Kar " << n << endl;
    }

    Kar(Kar &k){
        n = ++Kar::no;
        cout << "Copying Kar " <<k.n<< " to new Kar " << n << endl;
    }

    ~Kar(){
        cout << "Destroying Kar "<< n << endl;
    }

    Kar& operator= (const Kar &k);
};


Kar& Kar::operator= (const Kar &k){

    cout << "Assigning Kar "<< k.n <<" to Kar "<< this->n << endl;
    return *this;
}



int Kar::no;

Kar foo(){
    cout << "Starting foo()" << endl;
    Kar k;
    cout << "Finishing foo()" << endl;
    return k;
}


int main(int argc, char **argv) {
    cout << "Starting!" << endl;

    Kar k;
    k=foo();
    //     Kar k2 = foo();

    cout << "Finishing!" << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

终端输出是这样的:

Starting!
Creating Kar 1
Starting foo()
Creating Kar 2
Finishing foo()
Assigning Kar 2 to Kar 1
Destroying Kar 2
Finishing!
Destroying Kar 1
Run Code Online (Sandbox Code Playgroud)
  1. 我希望这种行为foo()是:a.创造Kar 2 b.将其复制到Kar 3并将其返回(随后将Kar 3分配给Kar 1).为什么不?

  2. 如果我取消注释,Kar k2 = foo();我会得到编译器消息:

    错误:没有用于调用Kar :: Kar(Kar)的匹配函数

结束当然我无法添加构造函数,Kar(Kar k){ }因为它无效.这是什么意思?为什么构造函数不Kar(Kar &k)用于这种情况?

con*_*t3d 5

您看到的行为称为返回值优化.因此,代替编译器为返回值创建临时对象,它将消除它,并使用在return语句之后已创建的对象.

关于你的第二个问题,你得到一个编译器错误,因为你不能将非常量临时值(r值)绑定到l值引用(BTW MSVC接受此但它是非标准行为).尝试将您的复制构造函数更改为:

Kar(const Kar& kar);