我还没有发现任何类似的问题:但是如果有人发现了一个问题,那就对不起。
我一直在尝试使用std::shared_ptr
来大大简化内存管理,但是我遇到了一定是某种错误的东西。
当我使用DerivedType
创建std::make_shared<type>(DerivedType(...))
指针时,只能将其寻址为Type
而不是DerivedType
。
但是,当我使用语法std::shared_ptr<Type>(new DerivedType)
时,vfptr
表列出了正确的条目,并且可以将其强制转换为DerivedType
而不会有问题。
我相信应该没有区别。就我所知这是一个错误吗?还是一个实际的错误?
谢谢你的帮助。
路加
最佳答案
您必须将要传递给类型的构造函数的参数传递给std::make_shared
,然后将它们转发。
然后,您可以将结果指针隐式转换为基本指针。
std::shared_ptr<Type> p = std::make_shared<DerivedType>(...);
让我们来探讨一下问题的“原因”。
std::shared_ptr<Type>(new DerivedType);
这确实有效,并且没有任何值得注意的事情。但是,通常首选
std::make_shared
,因为后者可以将std::shared_ptr
的簿记数据与您的对象一起分配,因此更快,更便宜,并且具有异常安全性*。std::make_shared<Type>(DerivedType(...))
您看到了:它不起作用。这里发生的是您创建一个
DerivedType
实例。 std::make_shared
愉快地将其转发到Type
的构造函数。发生重载解析,并调用
Type
的副本构造函数(或其移动构造函数,如果可用),并引用DerivedType
的基础部分。一个普通的Type
对象被实例化并指向。原始的DerivedType
消失了。整个问题称为切片。*关于异常安全性的注意事项:请使用以下形式的函数:
void func(std::shared_ptr<A> a, std::shared_ptr<B> b);
...像这样构造
std::shared_ptr
:func(std::shared_ptr<A>(new A), std::shared_ptr<B>(new B);
例如,如果调用
new A
,然后调用new B
,后者会引发异常,则可能会泄漏。 A
尚未包装到智能指针中,并且无法恢复。