dynamic_cast一个const const的非const引用。 cppreference.com的解释似乎很奇怪

时间:2013-12-29 19:27:02

标签: c++ casting dynamic-cast

我对可用的各种类型的可用内容进行了记忆,并在cppreference.com上发现了以下内容(http://en.cppreference.com/w/cpp/language/dynamic_cast):

  

1)如果表达式的类型是 new_type 的确切new_type或较少cv限定版本,则结果为 expression

参考结构

dynamic_cast < new_type > ( expression )

我将其解释为,例如,尝试对同一类型的const引用进行非const引用的dynamic_cast实际上会产生非const引用,因此允许我调用其非const成员, 与我期望的相反。我写了下面的noddy代码来检查出来:

#include<iostream>

class Base
{
  int value;
public:
  Base():value(0){};

  virtual void ShowVal() const
  {
    printf("Value is %d\n", 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);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我想我乞求的问题是:我是否误解了上述规则?如果是这样,实际上是说什么呢?是否有类似的基本示例来演示它?

感谢。 (与此同时,我将再次阅读它,如果我意识到我误读了它,那么我会很快删除这个问题并开始面对面...)

2 个答案:

答案 0 :(得分:2)

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

这是C ++ 11标准中的样子:

  

如果v的类型与T相同,或者它与T相同,只是T中的类对象类型更符合cv与v中的类对象类型相比,结果为v(必要时进行转换)。

请注意“必要时转换”。

你可能想知道为什么它甚至会说结果是expression?对于大多数dynamic_cast,结果是 expression。考虑从指向基类的指针转换为指向派生类的指针。你没有得到相同的指针。相反,您将获得指向派生子对象的指针。

答案 1 :(得分:0)

它表示表达式的类型可以 cv-qualified而不是 new-type 。结果的类型仍然是 new-type (值为表达式)。因为那是指定的。