dynamic_cast改变原始对象?

时间:2014-12-05 16:20:23

标签: c++ inheritance casting

为什么dynamic_cast<new>(old)会更改old

示例代码:

#include <iostream>
#include <string>

class MyInterface {
public:
  virtual void say() = 0;  
  virtual ~MyInterface() { }
};

class SubInterface : public MyInterface {
public:
  std::string test = "test";
  virtual void say() = 0;
  virtual ~SubInterface() { }
};

class Example : public SubInterface { 
public:
  void say() {
    std::cout << test << std::endl;
  } 
}; 


int main() {
  MyInterface* ex1 = new Example(); 
  SubInterface* ex2 = dynamic_cast<SubInterface*>(ex1);
  if (ex2 != nullptr) {
    std::cout << "call ex2->say(): ";
    ex2->test = "something else";
    ex2->say();
  }
  else { 
    std::cout << "error" << std::endl;
  }

  std::cout << "call ex1->say(): ";
  ex1->say();

  std::cerr << "debug: ex1=" << ex1 << "; ex2=" << ex2 << std::endl;

  return 0;
}

哪个输出:

call ex2->say(): something else
call ex1->say(): something else
debug: ex1=0xf1e010; ex2=0xf1e010

因此我希望ex2ex1不同,因此预期ex2->test = "something else";不会更改ex1。我想这是预期的行为,但为什么呢? (如果它们没有什么不同,为什么甚至有必要为dynamic_cast的结果分配任何内容?(可以继续使用ex1?)

感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

  

我想这是预期的行为,但为什么呢?

您正在转换指向其他类型的指针,而不是创建新对象。两者都指向相同的Example对象;一个将其视为MyInterface,另一个视为SubInterface。因此,在通过一个指针修改对象后,通过另一个指针对其进行更改,因为它们都指向同一个对象。

  

如果它们没有什么不同,为什么甚至需要为dynamic_cast的结果分配任何内容?

它们不一定相同。通过多重继承,不同的基类子对象可能位于整个对象内的不同位置。在这种情况下,向下转换可能必须调整指针值以指向整个对象。

  

可以继续使用ex1

没有。即使在您的情况下,它确实具有相同的值,但它的类型也是错误的。它被声明指向MyInterface,它没有test成员,所以你不能说ex1->test

答案 1 :(得分:1)

ex1和ex2指向同一个对象,但具有不同的类型。换句话说,内存是相同的(相同的Example对象),但是如何操作内存是通过两个不同的接口(MyInterface或SubInterface)完成的。

dynamic_cast是一个运行时强制转换,可用于通过不同(相关)接口安全地操纵数据,而不是另一个变量的类型允许。虽然你的例子当然不需要,但有很多用途。

答案 2 :(得分:1)

dynamic_cast所做的只是另外验证指向对象的实际类型是否与您期望的类型匹配,如果不符合则返回nullptr。如果它们匹配,则返回指向同一对象的指针,就好像你已经创建static_cast一样(比喻说,运行时检查旁边还有一些其他细微差别)。此附加验证不会创建新对象。 dynamic_cast没有改变对象 - 你做了。

答案 3 :(得分:1)

Dynamic_cast永远不会更改原始对象,在您的情况下&#39; ex1&#39;。最初分配的内存保持不变。否则,你会遇到各种泄漏和内存损坏。

你的意图似乎也是为了理解它是否能给你一个不同于输入的指针。

要理解这一点,你必须向两个方向推理 - 向上转发和向下转换以及继承和成员变量等。

其他人在这个问题上有很好的答案。建议搜索相关的。