函数是否应该返回指向堆上分配的内存的指针?
换句话说,下列哪种方法更多"正确"?
// 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
}
我想第一种方法可能更快,但第二种方法不需要用户删除对象。
答案 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
或其他任何东西......所以这对删除函数会实现delete
或free
或其他任何你需要的东西解除分配。