C++的上抛和下落

upcasting and downcasting in C++

本文关键字:C++      更新时间:2023-10-16

我尝试使用Visual Studio C++ 2010 Express和dynamic_cast在C++中进行投射的想法。 但不知何故,当我运行它时,猫对象实际上可以执行狗的行为。

看起来 Dogd = (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;
}

输出

建造动物猫

构造猫

你好哇...有效演员表

你好哇...斤

'

Dog *d = (Dog*)aa;

类型强制转换的括号样式称为 C 样式转换,因为它旨在模仿 C 的行为。 在这种情况下,编译器执行一个static_cast,它继续向下转换Animal*Dog*,假设底层对象是Dog因为底层对象实际上是Cat的,所以程序格式不正确,任何事情都可能发生,包括内存损坏。 C 型铸件从不执行任何运行时安全检查。

Dog* dog = dynamic_cast<Dog*>(d);

这个演员实际上不需要做任何事情:它正在从Dog*转换为Dog*。 即使使用了dynamic_cast,也不必执行运行时安全检查,因为假定d是格式正确的Dog*

建议

避免使用 C 型转换。 确保任何向下的投射都是有效的。 我个人不太使用dynamic_cast,但责任在于我只能适当地投掷。

Animal *aa = new Cat("Catty"); // cat upcasting to animal 
Dog *d = (Dog*)aa; // animal downcasting to dog. ???

这是未定义的行为,您需要一些有关v-table的低级实现的知识,以了解为什么调用会导致woof。在此之前,要知道应该避免未定义的行为。

Dog* dog = dynamic_cast<Dog*>(d);

由于 d 已经是一个 Dog*,编译器可能没有生成代码来执行 RTTI 并简单地分配它,因此它成功了。

相关文章:
  • 没有找到相关文章