C++:创建模板化的Shared <T>对象而不是shared_ptr <T>对象

JnB*_*ymn 2 c++ pimpl-idiom shared-ptr

根据我之前的问题,我希望a boost::shared_ptr<A>实际上是A(或许是A*)的子类,以便它可以用在A*作为参数的方法中.

考虑以下课程:

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

在上一个问题中,我提议创建一个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)

如果我可以创建一个模板类来为我处理所有这些问题,那将是Grrrrrrrrreat想的.

template <class T>
class Shared : public T
{
public:
    SharedT(T* t) : mImpl(t)
    {
    //What kind of crazy voodoo goes here?
    }

private:
    boost::shared_ptr<T> mImpl;
};
Run Code Online (Sandbox Code Playgroud)

如果我有这个,(以及正确的构造函数Shared<T>),那么我可以做到以下几点:

A* indestructo_A = new Shared<A>(new A(100));
A* indestructo_A_clone = new Shared<A>(indestructo_A);
delete indestructo_A
cout << "Indestructo-A back with a vengence!" << indestructo_A_clone.getX();
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 这有用吗?或者它的实用程序仅适用于处理特别糟糕代码的极端情况.例如:

    void aFunctionYouHaveToUse(A*a){/ 一些有用的算法然后/
    删除a; }

  2. 是否有可能建立这样的模板类?(我猜你需要反思,对吧?)如果你能建造它,怎么样?

Edw*_*nge 8

有一个非常好的理由,为什么shared_ptr不允许显式转换为A*(有更好的方法来做它而不是继承,这无论如何都是不可能的).shared_ptr和其他智能指针的全部目的是提供一个小的封装对象,其唯一目的是拥有一个指针并决定何时以及如何删除它.

如果这个对象允许同样的指针只是狡猾地传递,没有想到,那么它根本无法满足其目的.每当你深入了解智能指针以获取内部的原始指针时,都会违反其所有权语义,然后必须小心谨慎,不要做一些愚蠢的事情.智能指针会让你想到这一点,强迫你调用指针进入内部,而不是只是在你不小心将它传递给错误的函数时默默地这样做.想想它就像智能指针一样,"嘿,你知道你在做什么可能很危险,对吧?好吧,你走吧."

恕我直言,如果共享指针不允许访问其指针,宇宙将是一个更好的地方.不幸的是,这不是这个宇宙,也不可能是这个宇宙,因为偶尔你仍然需要将这个东西传递给一个不使用智能指针的函数.所以,既然我们没有生活在那个更好的宇宙中,我们的智能指针确实允许访问,它们只是不是它的贱人.