所以,我正在尝试做这样的事情
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>
没有问题。这是指向同一计数器的共享指针的另一个实例。