哪一个是更好的接口,用于将原始指针(由用户提供)保存到shared_ptr

时间:2012-03-06 17:11:32

标签: c++ design-patterns boost

在策略设计模式中,我需要在Composition中存储对Compositor的引用(pp315 GOF)。对于其中一个实现方法,客户端会将Compositor的引用传递给Composition的构造函数,我想知道从设计的角度来看哪个API接口更好。

例如:

1&GT; A(boost::shared_ptr<int> ptr) //假设ptr引用Compositor

2 - ; B(int* ptr) //假设ptr引用Compositor

我给出了以下示例来说明两个不同接口的用法。它们不是战略设计模式的实施!提供的代码是为了帮助我演示客户端可以使用对Compositor的引用的传入参数调用Composition的不同方法。

#include <boost/shared_ptr.hpp>
using namespace std; // for convenience
class A {
private:    
    boost::shared_ptr<int> m_sPtr;
public:
    A(boost::shared_ptr<int> ptr) : m_sPtr(ptr) {}
    //...
};

class B {
private:    
    boost::shared_ptr<int> m_sPtr;
public:
    B(int* ptr) : m_sPtr(ptr) {}
    //...
};

int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
    boost::shared_ptr<int> temPtr(new int(100));
    A a(temPtr);

    B b(new int(200));

    return 0;
}

谢谢

3 个答案:

答案 0 :(得分:2)

大多数情况下,创建资源的地方负责释放它的位置,因此除非你的类是智能指针,否则你不应该采用原始指针。

很快,使用C ++ 11中的可变参数模板,您将能够使用make_shared(),这意味着您根本不会调用new。

如果您希望对象保留共享副本,请将其传递给shared_ptr。顺便说一下,创建它的人也知道它是如何被销毁的,因此可以放入自定义删除器。

答案 1 :(得分:1)

如果您要将指针存储在shared_ptr中,那么 将其接受为shared_ptr,而不是原始指针(除非你'重新编写一个自己的智能指针类,它使用下面的shared_ptr。但你不是。)

原因只是用户可能已经将他们的资源放在shared_ptr中,例如,如果他们在创建后巧妙地将其放在那里。如果您为同一资源创建另一个shared_ptr,那么有两件事最终会删除它,这就是一个错误。

您可以通过将enable_shared_from_this与Compositor类一起使用来解决这个问题,但除非有一个很好的理由,否则您无法首先使用shared_ptr,这是没有意义的。

答案 2 :(得分:0)

最好始终(在特殊情况下极少数例外)将某个指针new分配的指针存储在某种智能指针中。因此,A中使用的程序是最好的。该接口明确强制指针传递的参数存储在智能指针中。您的班级B根本不保证。实际上,即使您在调用代码中不小心并调用write A(new int(100));,也可以确保指针不会被意外泄露,因为(临时)shared_ptr将从您的原始指针构造,然后传递给一个人的构造函数。 A中使用的界面宣布,&#34;你的指针将被处理!&#34;而B中的界面说,&#34;嗯......我不知道会发生什么事情!&#34;