我还没有发现任何类似的问题:但是如果有人找到了,那就很抱歉。
我一直在尝试使用std::shared_ptr
来大大简化内存管理,但是我发现了必然存在的错误。
当我使用DerivedType
创建std::make_shared<type>(DerivedType(...))
指针时,它只能作为Type
而不是DerivedType
来处理。
然而,当我使用语法std::shared_ptr<Type>(new DerivedType)
时,vfptr
表会列出正确的条目,并且可以毫无问题地转换为DerivedType
。
我相信应该没有区别。这是我理解中的错误吗?还是一个真正的错误?
感谢您的帮助。 路加
答案 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:突出显示更改