C++:创建共享对象而不是对象的共享指针

JnB*_*ymn 4 c++ pimpl-idiom smart-pointers shared-ptr

boost :: shared_ptr真让我烦恼.当然,我理解这种事情的实用性,但我希望我可以使用它shared_ptr<A> 作为一个A*.请考虑以下代码

class A
{
public:
    A() {}
    A(int x) {mX = x;}
    virtual void setX(int x) {mX = x;}
    virtual int getX() const {return mX;}
private:
    int mX;
};


class HelpfulContainer
{
public:
    //Don't worry, I'll manager the memory from here.
    void eventHorizon(A*& a)
    {
        cout << "It's too late to save it now!" << endl;
        delete a;
        a = NULL;
    }
};


int main()
{
    HelpfulContainer helpfulContainer;

    A* a1 = new A(1);
    A* a2 = new A(*a1);
    cout << "*a1 = " << *a1 << endl;
    cout << "*a2 = " << *a2 << endl;
    a2->setX(2);
    cout << "*a1 = " << *a1 << endl;
    cout << "*a2 = " << *a2 << endl;
    cout << "Demonstrated here a2 is not connected to a1." << endl;

    //hey, I wonder what this event horizon function is.
    helpfulContainer.eventHorizon(a1);

    cout << "*a1 = " << *a1 << endl;//Bad things happen when running this line.
}
Run Code Online (Sandbox Code Playgroud)

创建有用的容器的人并没有想到其他人想要保留指向A对象的指针.我们不能提供有助于类的boost :: shared_ptr对象.但我们能做的一件事是使用pimlp成语来创建一个本身就是A的SharedA:

class SharedA : public A
{
public:
    SharedA(A* a) : mImpl(a){}
    virtual void setX(int x) {mImpl->setX(x);}
    virtual int getX() const {return mImpl->getX();}
private:
    boost::shared_ptr<A> mImpl;
};
Run Code Online (Sandbox Code Playgroud)

然后主函数看起来像这样:

int main()
{
    HelpfulContainer helpfulContainer;

    A* sa1 = new SharedA(new A(1));
    A* sa2 = new SharedA(sa1);
    cout << "*sa1 = " << *sa1 << endl;
    cout << "*sa2 = " << *sa2 << endl;
    sa2->setX(2);
    cout << "*sa1 = " << *sa1 << endl;
    cout << "*sa2 = " << *sa2 << endl;
    cout << "this demonstrates that sa2 is a shared version of sa1" << endl;

    helpfulContainer.eventHorizon(sa1);
    sa2->setX(3);
    //cout << "*sa1 = " << *sa1 << endl;//Bad things would happen here
    cout << "*sa2 = " << *sa2 << endl; 
    //but this line indicates that the originally created A is still safe and intact.
    //only when we call sa2 goes out of scope will the A be deleted.
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:上面的模式是一个好的模式,还是我还没有考虑的东西.我当前的项目继承了一个HelpfulContainer像上面那样删除我需要的指针的类,但我仍然需要有用的容器中的数据结构.


更新:这个问题是一个后续问题.

CB *_*ley 6

重点shared_ptr是它(及其副本)拥有它指向的对象.如果您想要A一个管理其生命周期的容器,那么您根本不应该使用它shared_ptr,因为它不能满足您的需求; HelpfulContainer只知道如何成为动态创建对象的唯一所有者,因此您需要为其指定一个不属于其他任何对象的对象.

我认为对象关心自己的生命周期通常是糟糕的设计(有例外).如果一个对象可以完成一项工作而其他东西管理它的创建和解决,通常选择最简单的生命周期策略(例如本地/自动变量),这通常会更有用.

如果您必须在两个不合作的事物(例如shared_ptrHelpfulContainer)之间共享所有权,那么您将不得不使用某种代理技术.

但在这种情况下,它看起来HelpfulContainer只是对你的情况没有帮助.