为什么要像这样在 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 AB 的情况下,强制转换 (B)a 将通过调用 B::B(A&) 构造函数来构造新对象 class B.


当然,这种转换不是 dynamic_cast<> 应该用于的,因此 dynamic_cast<> 和 non-pointer/reference 类型被标准禁止。