为什么要像这样在 shared_ptr 上投射?
Why is casting on shared_ptr like this?
我看过一篇关于该主题的旧 post。由于我的新帐户和缺乏声望点,我无法在那里发表评论;因此,我正在做这个 post.
我过去一直在寻找一种方法,将共享指针从一种类型转换为另一种类型(从基类到派生类),以便访问派生端的一些私有成员。我知道最好避免向下转换,但这是框架...无论如何,我在原始 post 上看到的答案是:
std::shared_ptr<A> ap = ...;
dynamic_cast<B&>(*ap).b_function();
if (B* bp = dynamic_cast<B*>(ap.get())
现在,在命令中:dynamic_cast<B&>(*ap).b_function()
我知道这里的解除引用符号为我们提供了 shared_ptr 指向的对象的引用。我的问题是为什么我们需要 B 的参考(即 B&)?我们不能让它像这样工作吗:
B& Bref = dynamic_cast<B>(*ap);
Bref.b_function();
我对模板不是很熟悉(比如实现了shared_ptr),所以我想这是我对这件事的了解不足。有人可以向我解释 & 在这种情况下背后的含义以及为什么我给出的替代方案不起作用吗?
My question is why do we need a reference on the B
(i.e. B&
)? Couldn't we make it work as:
B& Bref = dynamic_cast<B>(*ap);
Bref.b_function();
不,你不能这样做。引用自 C++ 标准 [expr.dynamic.cast/1]:
The result of the expression dynamic_cast<T>(v)
is the result of converting the expression v
to type T
. T
shall be a pointer or reference to a complete class type, or “pointer to cv void
”.
要点是,转换为 non-pointer/reference 类型在 C++ 中始终是 转换 。您将获得与原始值不同的转换值。它是一个新的本地对象,在内存中有自己的位置。因此,对此副本的任何更改都不会影响原始值。
在 classes A
和 B
的情况下,强制转换 (B)a
将通过调用 B::B(A&)
构造函数来构造新对象 class B
.
当然,这种转换不是 dynamic_cast<>
应该用于的,因此 dynamic_cast<>
和 non-pointer/reference 类型被标准禁止。
我看过一篇关于该主题的旧 post。由于我的新帐户和缺乏声望点,我无法在那里发表评论;因此,我正在做这个 post.
我过去一直在寻找一种方法,将共享指针从一种类型转换为另一种类型(从基类到派生类),以便访问派生端的一些私有成员。我知道最好避免向下转换,但这是框架...无论如何,我在原始 post 上看到的答案是:
std::shared_ptr<A> ap = ...;
dynamic_cast<B&>(*ap).b_function();
if (B* bp = dynamic_cast<B*>(ap.get())
现在,在命令中:dynamic_cast<B&>(*ap).b_function()
我知道这里的解除引用符号为我们提供了 shared_ptr 指向的对象的引用。我的问题是为什么我们需要 B 的参考(即 B&)?我们不能让它像这样工作吗:
B& Bref = dynamic_cast<B>(*ap);
Bref.b_function();
我对模板不是很熟悉(比如实现了shared_ptr),所以我想这是我对这件事的了解不足。有人可以向我解释 & 在这种情况下背后的含义以及为什么我给出的替代方案不起作用吗?
My question is why do we need a reference on the
B
(i.e.B&
)? Couldn't we make it work as:
B& Bref = dynamic_cast<B>(*ap);
Bref.b_function();
不,你不能这样做。引用自 C++ 标准 [expr.dynamic.cast/1]:
The result of the expression
dynamic_cast<T>(v)
is the result of converting the expressionv
to typeT
.T
shall be a pointer or reference to a complete class type, or “pointer to cvvoid
”.
要点是,转换为 non-pointer/reference 类型在 C++ 中始终是 转换 。您将获得与原始值不同的转换值。它是一个新的本地对象,在内存中有自己的位置。因此,对此副本的任何更改都不会影响原始值。
在 classes A
和 B
的情况下,强制转换 (B)a
将通过调用 B::B(A&)
构造函数来构造新对象 class B
.
当然,这种转换不是 dynamic_cast<>
应该用于的,因此 dynamic_cast<>
和 non-pointer/reference 类型被标准禁止。