c++ - C++ 中的向上转换和向下转换
问题描述
我正在尝试使用 Visual Studio C++ 2010 Express 和使用 dynamic_cast 在 C++ 中进行投射的想法。但不知何故,当我运行它时,猫对象实际上可以执行狗的行为。
看起来像Dog d = (Dog )aa; 让编译器感到困惑。有什么建议吗?
下面是我的代码。
`
#include <iostream>
#include <string>
using namespace std;
class Animal {
public:
string name ;
Animal(string n) : name(n) {cout << "construct animal " << name << endl ; }
Animal() : name("none") { };
virtual string getName() { return name ; }
virtual ~Animal() { cout << "destruct animal " << name << endl ; }
};
class Dog: public Animal{
public:
Dog() :Animal("") { }
Dog(string n): Animal(n) {
cout << "construct Dog" << endl ;
}
void dogStuff() { cout << "hello woof...."; }
};
class Cat: public Animal{
public:
Cat() :Animal("") { }
Cat(string n): Animal(n) {
cout << "construct Cat" << endl ;
}
void catStuff() { cout << "hello meow...."; }
};
int main() {
Animal *aa = new Cat("Catty"); // cat upcasting to animal
Dog *d = (Dog*)aa; // animal downcasting to dog. ???
cout << d->getName() << endl;
d->dogStuff();
Dog* dog = dynamic_cast<Dog*>(d) ;
if(dog) {
cout << "valid cast" << endl ;
dog->dogStuff();
cout << dog->getName();
}else
cout << "invalid cast" << endl ;
int i ;
cin >> i ;
return 0;
}
输出
建造动物Catty
构造猫
斤
你好 woof....有效的演员表
你好,呜呜……猫
`
解决方案
Dog *d = (Dog*)aa;
类型转换的括号样式称为C 样式转换,因为它旨在模仿 C 的行为。在这种情况下,编译器执行 a static_cast
,然后继续向下转换Animal*
为Dog*
,假设基础对象是Dog
。因为底层对象实际上是Cat
,所以程序格式错误,任何事情都可能发生,包括内存损坏。C 风格的转换从不做任何运行时安全检查。
Dog* dog = dynamic_cast<Dog*>(d);
这个演员实际上不需要做任何事情:它从 转换Dog*
为Dog*
. 即使使用了运行时安全检查,也不必进行dynamic_cast
,因为d
假定它是格式良好的Dog*
.
建议
避免 C 风格的演员表。确保任何向下转换都是有效的。我个人用dynamic_cast
的不是很多,但我有责任只正确地沮丧。
推荐阅读
- rust - 实现基本类型的特征(浮点数)
- ios - 使用 FetchedResultsController 时 UITableView 中的部分不正确
- c - 链接器找不到外部引用
- r - 在森林函数中重复变量名
- python - Python - 将每个字符移动到字符串末尾而不重用原始字符串
- html - 在我的 C++ 程序中单击“帮助”按钮是否可以打开一个 html 页面?
- python - 开源板载文件同步 USB 程序。需要使用 config.ini 允许用户输入路径,但是有问题
- tensorflow - Tensorflow softmax 不忽略掩码值
- r - 在 Shiny 中动态排列图像
- sd-card - 从 SD 卡刷新 Google Coral 板失败并出现错误:“源”命令的图像格式错误