您必须传递给std::make_shared
您将传递给类型的构造函数的参数,并且它们是forwarded。
然后,您可以将结果指针隐式转换为基指针。
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
s :
func(std::shared_ptr<A>(new A), std::shared_ptr<B>(new B);
... 可能会泄漏,例如,如果new A
调用 then new B
,则后者会引发异常。A
尚未包装到智能指针中,并且无法恢复。