【问题标题】:Why doesn't the copy constructor work when I return an automatic variable from function?当我从函数返回自动变量时,为什么复制构造函数不起作用?
【发布时间】:2021-02-17 03:35:23
【问题描述】:

在下面的示例中,我想找出当我从 doit() 函数返回一个自动变量时,为什么不调用复制构造函数。我知道调用第一个版本的处理程序是因为我们有一个临时对象,但无法弄清楚为什么在创建该临时对象时不调用复制构造函数(将所有内容从 s 复制到临时对象)。

#include <iostream>
using namespace std;


class S{
    public:
        S(){std::cout<<"Constructor\n";}
        S(const S& s){std::cout<<"Copy Constructor\n";}
        ~S(){std::cout<<"Destructor\n";}
};

S doit(){
    S s;
    return s; 
}

void handler(S&& r){
    std::cout<<"Here\n";
}
void handler(const S& r){
    std::cout<<"Here2\n";
}

int main() {
    handler(doit());
}

【问题讨论】:

标签: c++ return-value temporary-objects return-by-value


【解决方案1】:

实际上,根据语言规则,在您的代码中调用了一个构造函数。但是,编译器已对其进行了优化,因此您看不到调用。如果您使用-fno-elide-constructors 编译,您应该会看到复制构造函数被调用。

请注意,复制构造函数只会被调用,因为默认的移动构造函数被抑制了。如果你像这样添加回来:

S(S&&) = default;

然后将调用此移动构造函数。这是demo

【讨论】:

  • 是这么想的,但不确定,因为我是在在线编译器中编译的
  • @ErikNouroyan 使用在线编译器应该没什么区别。
  • 其实可以,加S(S&amp;&amp;) = default; this 不会调用复制构造函数
  • @ErikNouroyan 是的,但是因为调用了移动构造函数。 (它与在线编译器无关)。查看演示链接,我在该构造函数中 cout 而不是默认它,以便您可以清楚地看到调用。
  • 啊,现在我明白了,谢谢,如果我这样做了S(S&amp;&amp;) = delete;,我希望它应该调用复制构造函数
猜你喜欢
  • 2013-12-08
  • 2013-08-24
  • 2019-11-07
  • 1970-01-01
  • 2015-11-02
  • 2021-01-04
  • 2015-06-10
  • 1970-01-01
相关资源
最近更新 更多