一个函数应该返回一个" new"宾语

时间:2017-04-14 17:21:05

标签: c++ function pointers return heap-memory

函数是否应该返回指向堆上分配的内存的指针?

换句话说,下列哪种方法更多"正确"?

// Method #1
Object* getObject1() {
    return new Object();
}

// Method #2
std::shared_ptr<Object> getObject2() {
    return std::make_shared<Object>();
}

int main() {
    // Usage of method #1
    Object* o1 = getObject1();
    o1->doSomething();
    delete o1; // object has to be deleted by user

    // Usage of method #2
    std::shared_ptr<Object>& o2 getObject2(); // has to be kept in shared_ptr
    o2.get()->doSomething();
    // object is deleted when o2 destructs
}

我想第一种方法可能更快,但第二种方法不需要用户删除对象。

3 个答案:

答案 0 :(得分:9)

在这两者中,第二个是首选。裸指针应该永远是你的最后选择。但理想情况下,您只需按值返回Object即可。如果不这样做,unique_ptr会优于shared_ptr,除非您确实需要共享所有权。

  

我想第一种方法可能更快。

对于shared_ptr,这可能是正确的。但是使用unique_ptr,编译器可以进行优化。由于手动删除的风险,没有任何好处可以帮助您回报。

答案 1 :(得分:3)

这两种选择都不是那么好。

默认情况下,您可以在C ++中做的最好的事情是:

Object getObject1() {
    return Object();
}

如果你真的 使用动态分配,那么你的首选应该是按值返回std::unique_ptr

std::unique_ptr<Object> getObject1() {
    return std::make_unique<Object>();
}

有关该主题的精彩文章,请参阅"GotW #90 Solution: Factories" by Herb Sutter。除其他外,Sutter说:

  
      
  • 返回unique_ptr表示返回唯一所有权,即   纯粹的“源”工厂功能的标准。
  •   
  • unique_ptr在效率方面无法击败 - 移动一个就像移动/复制原始指针一样便宜。
  •   

至于你的具体问题:

  

我想第一种方法可能更快,

std::shared_ptr涉及锁定以保证线程安全,因此可能会降低性能。但是,这应该不重要。动态分配通常总是比替代方案慢,因此您通常不希望在微观性能很重要的情况下使用它(例如在紧密循环中或在每秒执行多次的代码的某些部分中)。 C ++不鼓励您在免费商店中创建许多小对象。所以这样的功能首先不应该成为瓶颈。

答案 2 :(得分:0)

所有这些都是正确的。但是,创建一个删除&#34;是一个很好的做法。第一种情况的功能......

为什么?

因为你有一个&#34;界面&#34;那个负责分配对象,然后你应该有另一对进行重新分配,一旦这个功能的消费者使用你的界面,一个人不需要知道new正在发生例如,它可能是malloc或其他任何东西......所以这对删除函数会实现deletefree或其他任何你需要的东西解除分配。