您必须传递给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_ptrs :
func(std::shared_ptr<A>(new A), std::shared_ptr<B>(new B);
... 可能会泄漏,例如,如果new A调用 then new B,则后者会引发异常。A尚未包装到智能指针中,并且无法恢复。