[英]std::shared_ptr<type>(new DerivedType(…)) != std::make_shared<type>(DerivedType(…))?
I haven't found any issues quite like this yet: but if someone finds one then sorry. 我还没有发现任何类似的问题:但是如果有人找到一个问题,那就对不起。 I've been trying to use std::shared_ptr
to greatly simplify memory management, however I've come across what must be some sort of bug. 我一直在尝试使用std::shared_ptr
来大大简化内存管理,但是我遇到了一定是某种错误的东西。
When I create a DerivedType
pointer with std::make_shared<type>(DerivedType(...))
It can only be addressed as a Type
rather than a DerivedType
. 当我使用std::make_shared<type>(DerivedType(...))
创建DerivedType
指针时,只能将其寻址为Type
而不是DerivedType
。
Yet when I use the syntax std::shared_ptr<Type>(new DerivedType)
the vfptr
table lists the correct entries and it can be cast to a DerivedType
without a problem. 但是,当我使用语法std::shared_ptr<Type>(new DerivedType)
, vfptr
表列出了正确的条目,并且可以将其DerivedType
转换为DerivedType
。
I believe there should be no difference. 我相信应该没有区别。 Is this a bug in my understanding? 就我所知这是一个错误吗? or an actual bug? 还是一个实际的错误?
Thanks for your help. 谢谢你的帮助。 Luke 卢克
You must pass to std::make_shared
the parameters that you'd pass to your type's constructor, and they are forwarded . 您必须将传递给类型构造函数的参数传递给std::make_shared
,然后将它们转发 。
You can then convert the resulting pointer to a base pointer implicitly. 然后,您可以将结果指针隐式转换为基本指针。
std::shared_ptr<Type> p = std::make_shared<DerivedType>(...);
Let's dig a bit in the "why" in your question. 让我们来探讨一下问题的“原因”。
std::shared_ptr<Type>(new DerivedType);
This does work, and does nothing noteworthy. 这确实有效,并且没有任何值得注意的事情。 However, std::make_shared
is usually preferred, because the latter can allocate std::shared_ptr
's bookkeeping data along with your object, and thus is faster and cheaper, as well as exception-safe*. 但是,通常首选std::make_shared
,因为后者可以将std::shared_ptr
的簿记数据与您的对象一起分配,因此更快,更便宜,并且具有异常安全性*。
std::make_shared<Type>(DerivedType(...))
You saw it : it doesn't work. 您看到了:它不起作用。 What happens here is that you create a DerivedType
instance. 这里发生的是您创建了DerivedType
实例。 std::make_shared
happily forwards it to the constructor of Type
. std::make_shared
愉快地将其转发给Type
的构造函数。
Overload resolution happens, and Type
's copy constructor (or its move constructor, if available) is called, with a reference to your DerivedType
's base part. 发生重载解析,并调用Type
的副本构造函数 (或其移动构造函数,如果有),并引用DerivedType
的基础部分。 And a plain Type
object gets instantiated and pointed to. 一个普通的Type
对象被实例化并指向。 The original DerivedType
vanishes. 原始的DerivedType
消失了。 This issue as a whole is called slicing . 整个问题称为切片 。
* Note on exception safety : Shoud you use a function of the form : *关于异常安全性的注意事项:请使用以下形式的函数:
void func(std::shared_ptr<A> a, std::shared_ptr<B> b);
... constructing the std::shared_ptr
s like so : ...像这样构造std::shared_ptr
:
func(std::shared_ptr<A>(new A), std::shared_ptr<B>(new B);
... can leak if, for example, new A
is called, then new B
, and the latter throws an exception. 例如,如果调用new A
,然后调用new B
,则后者可能会引发异常。 The A
has not yet been wrapped into a smart pointer, and is unrecoverable. A
尚未包装到智能指针中,并且不可恢复。
std::make_shared<type>(DerivedType(...))
HEre replace make_shared<Type>
with make_shared<DerivedType>
and it all should work 在这里用make_shared<DerivedType>
替换make_shared<Type>
,这一切都应该工作
upd: highlighted the change upd:突出显示更改
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.