1

众所周知,为了避免内存泄漏,我们最好使用 SmartPtr 来管理对象,而不是使用普通指针。

在大多数情况下,它工作得很好。

现在我遇到一个问题,我尽量把它描述得更简单。

我有一个基类:

class Base;

我从基类继承了另外两个类:

class Derive1 : public Base;

class Derive2 : public Base;

如果我使用原始指针,我可以很容易地实现多态;</p>

Base *pd1 = new Derive1();

Base *pd2 = new Derive2();

但是如果我想用它smartPtr来实现同样的事情我应该怎么做呢?例如:

SmartPtr<Base> pd1 = SmartPtr<Derive1>(new Derive1);

有没有smartPtr支持转换,还是需要自己实现一个模板smartPtr,但是如果我自己实现模板,如何避免代码臃肿,谁有好的建议?

如果有模板 smartPtr 支持这个操作,它是如何完成这个功能的呢?正如我们所知,基指针可以指向派生对象,但反过来又不好!!

4

4 回答 4

4

只要你有一个虚拟析构函数,销毁对象就可以正常工作Base

class Base {
  public:
    virtual ~Base();
    ...
};
于 2013-07-24T13:53:45.660 回答
1

您不需要实现自己的智能指针模板,使用std::unique_ptrstd::shared_ptr.

例如,这将按照您想要的方式工作,利用多态行为。

std::unique_ptr<Base> sptr1{new Derive1()};
std::unique_ptr<Base> sptr2{new Derive2()};

也就是说,您可以像使用sptr1&sptr2一样使用:

Base* pd1 = new Derive1();
Base* pd2 = new Derive2();

sptr1&sptr2超出范围时,Base::~Base()将调用析构函数并Base删除指向 -object 的内部指针。使~Base()virtual 在销毁时也分别调用~Derive1()~Derive2()(与没有智能指针的情况相同)。

现场示例:http: //ideone.com/zVebLV

sptr1指向另一个派生对象,请执行以下操作:

sptr1 = sptr2; // This will destruct previous object pointed to by sptr1.
               // Will also set sptr2 = nullptr.

有关智能指针的更多信息: C++11 智能指针策略

于 2013-07-24T13:52:15.330 回答
1

你是在问“这行代码应该如何工作?”?

SmartPtr<Base> pd1 = SmartPtr<Derive1>(new Derive1);

我最好的建议是查看shared_ptr. 基本上它使用一个模板化的构造函数,允许你从另一个构造一个共享指针。显然,底层指针类型必须兼容......

template<class Y> shared_ptr( shared_ptr<Y> const & r )
: px( r.px ), pn( r.pn ) 
{
}

当然,您可以避免这种情况,只需首先编写此代码即可:-

SmartPtr<Base> pd1(new Derive1);
于 2013-07-24T14:27:59.147 回答
1

如果你在谈论std::shared_ptr<T>or unique_ptr<T>,那么是的,它会处理这种情况,因为它在内部存储类型的数据T*,在这种情况下Base*。所以你可以这样使用它。否则它们不会有太大用处。

于 2013-07-24T13:45:15.917 回答