首页 > 解决方案 > 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....有效的演员表

你好,呜呜……猫

`

标签: c++dynamic-castdowncastupcasting

解决方案


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的不是很多,但我有责任只正确地沮丧。


推荐阅读