std :: shared_ptr <type>(new DerivedType(...))!= std :: make_shared <type>(DerivedType(...))?</type> </type>

时间:2015-02-13 00:44:20

标签: c++ c++11 shared-ptr c++-standard-library make-shared

我还没有发现任何类似的问题:但是如果有人找到了,那就很抱歉。 我一直在尝试使用std::shared_ptr来大大简化内存管理,但是我发现了必然存在的错误。

当我使用DerivedType创建std::make_shared<type>(DerivedType(...))指针时,它只能作为Type而不是DerivedType来处理。

然而,当我使用语法std::shared_ptr<Type>(new DerivedType)时,vfptr表会列出正确的条目,并且可以毫无问题地转换为DerivedType

我相信应该没有区别。这是我理解中的错误吗?还是一个真正的错误?

感谢您的帮助。 路加

2 个答案:

答案 0 :(得分:4)

您必须将传递给类型构造函数的参数传递给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,后者会抛出异常。 <{1}}尚未被包装成智能指针,并且无法恢复。

答案 1 :(得分:-3)

std::make_shared<type>(DerivedType(...))

make_shared<Type>替换make_shared<DerivedType>,这一切都可以正常工作

upd:突出显示更改