首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSCV、构造函数、析构函数和NRVO行为

MSCV、构造函数、析构函数和NRVO行为
EN

Stack Overflow用户
提问于 2016-02-29 13:49:44
回答 1查看 95关注 0票数 0

我想知道NRVO是否在我正在进行的项目中处于活动状态(即Qt,使用MSVC 2013 64位)。

所以我写了一段代码:

代码语言:javascript
复制
class foo
{
public:
    foo(){qDebug() << "foo::foo";}
    foo(const foo& c){(void)c;qDebug() << "foo::foo( const foo& )\n";}
    ~foo(){qDebug() << "foo::~foo";}
};
foo             bar()
{
    foo local_foo;
    return (local_foo);
}
void                    func()
{
    foo f = bar();
}

它给了我以下的输出:

foo::foo foo::~foo

我上面提到的链接期望的是:

foo::foo() foo::foo( const foo& ) foo::~foo() foo::~foo()

但当我把酒吧电话换成

代码语言:javascript
复制
foo f = foo(bar())

然后我得到与链接相同的输出。

下面是我的问题:为什么"foo f= bar()“不调用复制构造函数?它是否调用了operator=,在调用之前,f是原始存储?(那么,为什么从2004年开始的链接就不一样了)?所以我必须得出结论,NRVO没有打开,对吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-29 14:16:07

为什么"foo f= bar()“不调用复制构造函数?

因为编译器允许埃利德复制。

它是否调用了operator=,在调用之前,f是原始存储?

不是的。

那么为什么2004年的链接不一样呢?

他们可能使用了另一个编译器、编译器的另一个版本或编译器的其他设置,而他们的编译器并没有删除该副本。

所以我必须得出结论,NRVO没有打开,对吗?

从第一个输入,您可以得出NRVO 打开的结论。从第二个输出可以得出结论,有一个副本没有被删除。但是,由于打印的副本比没有NRVO的副本少,所以您可以得出结论,NRVO是打开的,但并不适用于所有副本。

那么,"foo f= bar()“和foo f=foo(bar())之间有什么区别呢?

第一个副本从f的返回值初始化bar()

第二个构造器显式地使用复制构造函数构造一个临时对象,然后从该临时对象复制初始化f。这两份副本都可以删掉。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35701281

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档