共享指针继承,而不先显式强制转换



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

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);
}

它无法解析继承,因为它们是共享指针。理想情况下,我不想在 main 中使用static_pointer_cast或类似的东西,所以我正在寻找一种不同的方法来转换它,以便 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函数的作用域结束,它就会删除指针,从而导致双重释放错误,因为 main 中的共享 ptr 也试图删除它。

有什么建议可以尝试吗?

首先,在不需要所有权的地方使用智能指针是一种不好的做法。在您的情况下,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>没有问题。这是指向同一计数器的共享指针的另一个实例。

最新更新