首页 > 解决方案 > 共享指针继承,无需先显式转换

问题描述

所以,我正在尝试做这样的事情

template <typename T>
void call(std::shared_ptr<Base<T>> b) {

} 


int main() {
   std::shared_ptr<Derived<int>> d = std::make_shared<Derived<int>>();
   call(d);
}

它无法解决继承问题,因为它们是共享指针。理想情况下,我不想static_pointer_cast在 main 中使用或类似的东西,所以我正在寻找一种不同的方式来转换它,以便 main 中的用户仍然可以调用相同的函数,但不必担心转换。

我的第二种方法是使用原始指针,所以我尝试了这样的方法:

template <typename T>
void call(Base<T> * b) {
   std::shared_ptr<Base<T>> obj(b);
} 


int main() {
   std::shared_ptr<Derived<int>> d = std::make_shared<Derived<int>>();
   call(d.get());
}

由于 Base 是一个抽象类,我不能使用 make_shared 所以我必须以我的知识这样做,但是问题就变成了,一旦call函数的作用域结束,它就会删除指针,从而导致双重释放错误,因为共享 ptr在 main 中也尝试删除它。

有什么建议可以尝试吗?

标签: c++smart-pointers

解决方案


首先,在不需要所有权的地方使用智能指针是一种不好的做法。在您的情况下,该main函数拥有指针,并且在执行该函数时无法销毁该对象call。所以你可以毫无问题地传递一个原始指针(这更好,因为接口不需要比它需要的更多)。然而,在多线程环境的情况下,或者如果call函数具有存储指针的副作用(例如,set如果是类,那实际上是一个方法),这可能不是真的。在这种情况下shared_ptr确实应该使用。

接下来,您可以shared_ptr<Base>使用指向 的指针创建一个初始化它Derived。您甚至不需要使用虚拟析构函数来删除对象: shared_ptr 知道实际类型:

{
    std::shared_ptr<Base> d = std::make_shared<Derived>();
    // Ok to delete
}

shared_ptr<Derived>最后,投射到没有问题shared_ptr<Base>。这是指向同一个计数器的共享指针的另一个实例。


推荐阅读