dynamic_cast更改原始对象
dynamic_cast changes original object?
为什么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
?
任何帮助,不胜感激。
我想这是有意的行为,但为什么呢?
您正在将指针强制转换为其他类型,而不是创建新对象。两者都指向同一个Example
对象;一个把它当作MyInterface
,另一个把它当作SubInterface
。因此,通过一个指针修改对象后,对它的更改可以通过另一个指针可见,因为两者都指向同一对象。
如果它们没有不同,为什么甚至有必要为
dynamic_cast
的结果分配任何东西?
它们不一定相同。使用多重继承时,不同的基类子对象可能位于整个对象中的不同位置。在这种情况下,向下强制转换可能必须调整指针值以指向整个对象。
人们可以继续使用
ex1
?
不。即使像您一样,它确实具有相同的值,它也具有错误的类型。它声明指向MyInterface
,它没有test
成员,所以你不能说ex1->test
。
ex1 和 ex2 指向同一个对象,但类型不同。 换句话说,内存是相同的(相同的示例对象(,但如何操作内存是通过两个不同的接口(MyInterface或子接口(完成的。
dynamic_cast 是一个运行时强制转换,可用于通过不同于另一个变量类型所允许的不同(相关(接口安全地操作数据。 这有很多用途,尽管您的示例当然不需要它。
dynamic_cast
所做的只是另外验证指向对象的实际类型是否与您期望的类型匹配,如果不匹配,则返回nullptr
。如果它们确实匹配,它将返回指向同一对象的指针,就好像您进行了static_cast
一样(形象地说,除了运行时检查之外还有其他一些细微的差异(。此附加验证不会创建新对象。 dynamic_cast
没有改变对象——你改变了。
Dynamic_cast永远不会更改原始对象,在您的例子中为"ex1"。最初分配的内存保持不变。否则,您将遇到各种泄漏和内存损坏。
您的意图似乎也是了解它是否可以为您提供与输入指针不同的指针。
要理解这一点,您必须在两个方向上进行推理 - 向上转换和向下转换以及继承和成员变量等。
在这个问题上,其他人有很好的答案。建议搜索相关的。
- C ++引用函数参数似乎包含原始对象的副本,而不是充当"real reference"
- 如何在C++中将类的实例完全重新分配给同一类的另一个实例(然后删除原始对象)?
- C++修改通过引用传递的类不会更改原始对象
- 在保持原始对象的同时移动
- 在原始对象上使用惯用(例如 TBB 的 thread_enumerable_specific')移动赋值调用析构函数
- 操作员重载=修改原始对象
- 将新对象shared_pt分配给 A[1],则 A[1] 中包含的原始对象的引用计数减少.如何
- 是否可以按值传递临时对象而不破坏C++中的原始对象
- 基类类型的指针忘记了原始对象类型
- dynamic_cast更改原始对象
- C++:复制构造函数正在删除原始对象中的节点
- 为什么他们在原型模式中这么说 - 用于在需要新对象时简单地复制原始对象
- C++ 如何确保复制构造函数不会修改原始对象的指针数据成员?
- 处理程序捕获的对象是原始对象的副本
- 向文件写入/读取原始对象
- 如果我返回unique_ptr,原始对象会被删除吗
- 在编译器之间读取和写入原始对象到磁盘(istream)
- 原始对象的c++指针和复制对象的指针
- 为什么取消引用unique_ptr不会修改原始对象
- ++和+=运算符不修改原始对象是否"incorrect behaviour"?