std::shared_ptr<type>(new DerivedType(...)) != std::make_shared<type>(DerivedType(...))?
std::shared_ptr<type>(new DerivedType(...)) != std::make_shared<type>(DerivedType(...))?
我还没有发现任何类似这样的问题:但如果有人找到了,那就抱歉了。
我一直在尝试使用 std::shared_ptr
来大大简化内存管理,但是我遇到了一定是某种错误。
当我用 std::make_shared<type>(DerivedType(...))
创建一个 DerivedType
指针时,它只能作为 Type
而不是 DerivedType
来寻址。
然而,当我使用语法 std::shared_ptr<Type>(new DerivedType)
时,vfptr
table 列出了正确的条目,并且可以毫无问题地转换为 DerivedType
。
我相信应该没有区别。这是我理解中的错误吗?还是真正的错误?
感谢您的帮助。
卢克
std::make_shared<type>(DerivedType(...))
HERe 将 make_shared<Type>
替换为 make_shared<DerivedType>
,这一切都应该有效
更新:突出显示更改
您必须将要传递给类型的构造函数的参数传递给 std::make_shared
,并且它们是 转发。
然后您可以将结果指针隐式转换为基指针。
std::shared_ptr<Type> p = std::make_shared<DerivedType>(...);
让我们深入了解一下您问题中的 "why"。
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
消失了。这个问题作为一个整体被称为 slicing.
* 关于异常安全的注意事项: 你应该使用以下形式的函数吗:
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
,然后调用 new B
,则可能会泄漏,后者会抛出异常。 A
还没有被包装成智能指针,无法恢复。
我还没有发现任何类似这样的问题:但如果有人找到了,那就抱歉了。
我一直在尝试使用 std::shared_ptr
来大大简化内存管理,但是我遇到了一定是某种错误。
当我用 std::make_shared<type>(DerivedType(...))
创建一个 DerivedType
指针时,它只能作为 Type
而不是 DerivedType
来寻址。
然而,当我使用语法 std::shared_ptr<Type>(new DerivedType)
时,vfptr
table 列出了正确的条目,并且可以毫无问题地转换为 DerivedType
。
我相信应该没有区别。这是我理解中的错误吗?还是真正的错误?
感谢您的帮助。 卢克
std::make_shared<type>(DerivedType(...))
HERe 将 make_shared<Type>
替换为 make_shared<DerivedType>
,这一切都应该有效
更新:突出显示更改
您必须将要传递给类型的构造函数的参数传递给 std::make_shared
,并且它们是 转发。
然后您可以将结果指针隐式转换为基指针。
std::shared_ptr<Type> p = std::make_shared<DerivedType>(...);
让我们深入了解一下您问题中的 "why"。
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
消失了。这个问题作为一个整体被称为 slicing.
* 关于异常安全的注意事项: 你应该使用以下形式的函数吗:
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
,然后调用 new B
,则可能会泄漏,后者会抛出异常。 A
还没有被包装成智能指针,无法恢复。