dynamic_cast const ref 到 const ref. cppReference.com 的解释似乎很奇怪

dynamic_cast a non-const ref to a const ref. cppreference.com's explanation seems odd

本文关键字:ref const 解释 com cast cppReference dynamic      更新时间:2023-10-16

我正在刷新我对各种类型的选角的记忆,并在cppreference.com上发现了以下内容(http://en.cppreference.com/w/cpp/language/dynamic_cast):

1)如果表达式的类型正是new_type的new_type或不太符合cv的版本,则结果为表达

参考结构

dynamic_cast < new_type > ( expression )

我将其解释为,例如,尝试将一个非常量引用的dynamic_cast转换为同一类型的常量引用,实际上会产生非常量引用,因此允许我调用其非常量成员,这与我所期望的相反。我写了下面的一段代码来验证这一点:

#include<iostream>
class Base
{
int value;
public:
Base():value(0){};
virtual void ShowVal() const
{
printf("Value is %dn", value);
}
virtual void SetVal(int val)
{
value = val;
}
};
int main ()
{
Base b;
Base& rB = b;
b.ShowVal();
(dynamic_cast<const Base&>(rB)).SetVal(2); //fails where (dynamic_cast<Base&>(rB)).SetVal(2); is obviously fine.
b.ShowVal();
}

正如我所预料的那样,这个没有编译,我得到了错误

blah.cpp:28:3: error: member function 'SetVal' not viable: 'this' argument has type 'const Base', but function is not marked const
(dynamic_cast<const Base&>(rB)).SetVal(2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我想我要问的问题是:我误解了上面的规则吗?如果是这样的话,实际上在说什么?有没有类似的基本例子可以证明这一点?

谢谢。(在此期间,我将再次阅读,如果我意识到我误读了它,那么我会迅速删除这个问题,并开始掌纹…)

从编写的方式来看,这并不明显,但转换仍然会发生。这只是意味着从转换中获得的对象(指针或引用)与expression表示的对象相同。不过,强制转换表达式是const类型的,因为这就是您将其转换为的类型。

以下是它在C++11标准中的样子:

如果v的类型与T相同,或者与T相同,只是T中的类对象类型比v中的类目标类型更具cv限定性,则结果为v(必要时转换)。

请注意"converted if necessary"。

你可能会想,为什么说结果是expression会很麻烦?对于大多数dynamic_casts,结果是而不是expression。考虑将指向基类的指针强制转换为指向派生类的指针。你不会从中得到相同的指针。相反,你会得到一个指向派生子对象的指针。

它说表达式的类型可以是更少cv合格。结果的类型仍然是new(值为表达式)。因为这是指定的。