为什么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
因此我希望ex2
与ex1
不同,因此预期ex2->test = "something else";
不会更改ex1
。我想这是预期的行为,但为什么呢? (如果它们没有什么不同,为什么甚至有必要为dynamic_cast
的结果分配任何内容?(可以继续使用ex1
?)
感谢任何帮助。
答案 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;。最初分配的内存保持不变。否则,你会遇到各种泄漏和内存损坏。
你的意图似乎也是为了理解它是否能给你一个不同于输入的指针。
要理解这一点,你必须向两个方向推理 - 向上转发和向下转换以及继承和成员变量等。
其他人在这个问题上有很好的答案。建议搜索相关的。