【问题标题】:Returning C++ Object - Best Practice [duplicate]返回 C++ 对象 - 最佳实践
【发布时间】:2014-06-16 13:25:49
【问题描述】:

我是 C++ 新手,遇到以下问题:

假设您有一个创建新对象并返回该对象的函数。最好的方法是什么? 我找到了 3 种不同的解决方案。

解决方案一使用复制构造函数

MyClass getMyClass() {
    MyClass obj;
    //work with obj, set values...
    return obj;
}

据我了解,您创建一个新对象,复制该对象,销毁第一个对象并返回复制的对象。所以我创建了两个对象,但我只需要一个。对吗?

解决方案2在堆上创建对象并使用指针

MyClass* getMyClass() {
    MyClass* obj = new MyClass();
    //work with obj, set values...
    return obj;
}

这似乎是最糟糕的解决方案,您必须自己进行内存管理。

解决方案3将对象作为参数传递

MyClass getMyClass(MyClass& obj) {
    //work with obj, set values...
    return obj;
}

您创建一个默认对象并在函数中设置所有值。

我也想过使用unique_ptr<MyCLass>,但也有同样的问题,当函数范围离开时unique_ptr被销毁。

【问题讨论】:

  • 你应该考虑 shared_ptr cplusplus.com/reference/memory/shared_ptr 也可以使用移动语义cplusplus.com/reference/algorithm/move
  • 在解决方案 1 的情况下,编译器应该能够应用命名返回值优化并在其最终目的地构造对象。
  • 对于解决方案 2,请使用 std::shared_ptr。这三种解决方案都有自己的用例,一般来说没有一个更喜欢。
  • @Dlotan 不,如果你想要共享所有权,你应该只考虑shared_ptr。这种情况很少见。
  • “当函数作用域离开时unique_ptr 被销毁”——除非你从函数中返回它。 unique_ptr 是可移动的。

标签: c++ oop


【解决方案1】:

解决方案 1 不使用复制构造函数,而是使用 return value optimization。这意味着函数中构造的对象实际上并没有被复制,而是直接传递给函数的调用者。解决方案 1 是一个非常好的选择,我建议将它用于不使用太多堆栈空间的非多态对象(即无继承)。

多态对象的首选方法是解决方案 2。但请始终考虑谁拥有您的对象,即谁负责调用 delete。一个不错的选择是使用shared_ptrunique_ptr

解决方案 3 并没有真正创建对象,它只在它已经创建后才可以使用。在这里返回对象也没有意义。

【讨论】:

    【解决方案2】:

    每一个都有自己的用例,在所有情况下,你不能说其中一个比另一个更好或最差。这一切都归结为您的对象、您如何创建它们、它们应该与什么接口以及它们在哪里使用。

    还有第四个,通过使用共享指针 shared_ptr(如果您需要共享所有权)或自动指针(unique_ptrauto_ptr(有点不推荐))返回。

    比如接受引用的也不需要返回对象,这是一个额外的操作。

    返回指针的可能不需要包含头文件,一个简单的前向声明可能就足够了(至少当您在头文件中声明函数时)。但是为此,您当然需要手动管理内存(再次重申:共享指针在这里可能会有所帮助)。

    【讨论】:

    • 前向声明不足以构造带有new 的对象。
    • @DevSolar 编辑了问题(正在进行中)
    • 为什么是 shared_ptr?我看不到需要共享所有权的建议。
    • 别那么麻烦,反正问题是重复的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多