【问题标题】:Weird casting behaviour奇怪的铸造行为
【发布时间】:2011-05-27 14:52:37
【问题描述】:

谁能解释一下代码的输出。

#include <iostream>

using namespace std;

class First {
        public:
                int a;
                First() {};
                First(int a) {
                        this->a = a;
                }

                int getA() {
                        return a;
                }

                virtual int getB() {
                        cout << "getB() from super class..." << endl;
                        return 0;
                }
};

class Second : public First {
        public:
                int b;
                Second(int b) {
                        this->b = b;
                }

                int getB() {
                        cout << "getB() from child class..." << endl;
                        return b;
                }

};

int main() {
        First* t = new Second(2);
        First* cTest = dynamic_cast<First*>(t);
        cout << cTest->getB() << endl;

}

我预计超类的方法会因为转换为 First 而被调用。

提前致谢

问候塞巴斯蒂安

【问题讨论】:

  • 哦不,8个空格的缩进伤害了我的眼睛
  • 貌似是面试题……
  • 输出是:getB() from child class... 2
  • 您将 First* 转换为 First*... 为什么需要演员表?

标签: c++ casting polymorphism virtual


【解决方案1】:

函数getB()是基类中的virtual,所以无论你有指向基类的指针还是指向派生的指针,你都会得到派生的实现。

(这就是多态性的全部目的。)

【讨论】:

    【解决方案2】:

    层次结构的动态转换不会改变您仍然指向 B 的基本事实。特别是,它不会改变用于查找将使用的 getB() 实现的 vtable。

    通常,您只需要 dynamic_cast() 向下继承层次结构,而不是向上。

    【讨论】:

    • 他不是在构建层次结构,而是将 First* 转换为 First*。
    【解决方案3】:

    只有一个对象,它的类型是 Second。

    要获得您正在寻找的行为,您必须创建一个副本并对其进行切片:

    First cTest = static_cast<First>(*t);
    cout << cTest.getB() << endl;
    

    【讨论】:

    • 目前还不清楚真正的需求是什么,但明确地调用基类版本可能会更好:ideone.com/YD6H0
    【解决方案4】:

    你的演员表并没有改变任何东西。您正在将 First* 转换为 First*,这只是一个分配。由于 t 是带有 = new Second(2) 的 Second,因此您已经用子项的条目覆盖了虚拟表,因此它将调用子项的方法而不是父项。

    cTest 只是一个指向 First 的指针,它指向与 t 完全相同的对象,因为 cTest 和 t 包含相同的内存地址,其中存在 Second 对象,这就是调用 Second 方法的原因。

    【讨论】:

    • 有没有办法“真正”将它投射到 First ?这样就用 First 的方法代替了吗?
    • @Sebastian:在你用派生类的方法替换了所有虚拟表条目之后,我不知道你可以恢复哪个。如果您发布更大的问题,我们或许可以帮助您找出解决问题的不同方法。
    • @Sebastian:根据下面的 DanDan,您可以将指针和 static_cast 取消引用到 First 对象。这会奏效,但我强烈建议找出一种更好的方法来解决您要解决的任何问题。
    猜你喜欢
    • 2019-07-07
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 2019-05-12
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多