繁体   English   中英

在C ++中通过函数调用创建对象

[英]Creating an object by function call in C++

我想通过函数调用创建一个对象,我只会使用一次。

我尝试过的两种方法给出了相同的结果,但由于我是C ++的新手,我不确定它们是否合适。

#include <iostream>
using namespace std;

struct Foo {
    Foo(const int x, const int y): x(x), y(y) {};
    Foo(Foo & myfoo): x(myfoo.x), y(myfoo.y) {
        cout << "copying" << endl;
    };
    const int x, y;
};

int sum(const Foo & myfoo) {
    return myfoo.x + myfoo.y;
}

Foo make_foo(const int x, const int y) {
    Foo myfoo (x, y);
    return myfoo;
}

int main () {
    // version 1
    cout << 1 + sum(Foo(2,3)) << endl;
    // version 2
    cout << 1 + sum(make_foo(2,3)) << endl;
}

以下哪种方法“更正确”? 有什么不同? 我用gcc和clang运行上面的代码,两次都得到了

6
6

这意味着复制构造函数不会被调用。

相关: 在没有new的情况下用c ++调用构造函数

编辑:谢谢,我已经知道了RVO。 我只是想知道一种方法是否优先于另一种方法

在这种情况下,这两种方法是等效的。

您正在观察的是Copy elision ,或者更具体地说是返回值优化

编译器足够聪明,可以识别您不需要构建中间实例,因为您只是要复制,然后销毁它。 因此,它只是创建最终实例,它是函数返回的目标。

语言标准明确允许此优化,即使这意味着您的副本构造函数被绕过。 换句话说,无法保证调用复制构造函数的功能。

不调用复制构造函数,因为在sum(const Foo & myfoo)myfoo通过引用传递,因此不需要复制。 恕我直言我会说,一个普遍适用的Foo构造函数足以创建一个实例。 如果你有专门的功能会使你的Foo类与构造函数混乱,那么在其他地方有一个函数可能会更优雅,比如Foo loadFooFromFile(string filename)

值得注意的是,通常使用make_*命名的函数对于需要模板参数的类型非常有用(并且可以在构造期间推导出它们)。

在C ++类中,在调用构造函数时不会推导出模板参数(这将在C ++ 17中更改),因此您必须手动键入它们。 通过创建一个创建对象的函数,您可以自动为其推导出它。

例如,查找std::tuplestd::pair

编辑

我找到了一个非常相关的线程推理功能

在第一种情况下,cout << 1 + sum(Foo(2,3))<< endl; 由于sum接受Foo引用,因此不会调用复制构造函数。 对于以后的情况,您的编译器正在执行RVO,因此不会调用复制构造函数。 有关详细信息,请参阅Return Value OptimizationCopy Elision 此问题还有更多细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM