微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++ 中的类型混淆

如何解决C++ 中的类型混淆

我指的是这个link

#include <iostream>
using namespace std;


class Base {}; // Parent Class

class Execute: public Base {   // Child of Base Class
public:
    virtual void exec(const char *program) 
    {
        system(program);
    }
};

class Greeter: public Base {   // Child of Base Class
public:
    virtual void sayHi(const char *str) 
    {
        cout << str << endl;
    }

};


int main() {

    Base *b1 = new Greeter();
    Base *b2 = new Execute();
    Greeter *g;

    g = static_cast<Greeter*>(b1); // Safe Casting to the same type "Greeter"
    g->sayHi("Greeter says hi!"); // String passed to sayHi() function

    g = static_cast<Greeter*>(b2); // Unsafe Casting to sibling class "Execute"
    g->sayHi("/usr/bin/xcalc"); // String passed to exec() function 
                                    // which will turn into a command to execute calculator

    delete b1;
    delete b2;
    return 0;
}

我的问题是关于陈述的:

g = static_cast<Greeter*>(b2);
g->sayHi("/usr/bin/xcalc");

b2Execute 类型的实例。 b2 实例将有一个指向包含 exec() 条目的 vtable 的 vpointer。当下一条语句调用g->sayHi(..)时,vtable将如何用于查找调用哪个函数

参考link,它指出:

函数名用作 vtable 的索引以找到正确的 (最具体的)要执行的例程

如果使用了函数名,那么如何在 vtable 中找到 sayHi 类型的名称 Execute

解决方法

名称在编译时映射到 vtable 中的索引,因此在运行时函数调用只是一个数组查找。

有问题的代码导致未定义行为,因为 b2 不是 Greeter*。 (dynamic_cast 将返回 nullptr。)一种可能的结果是 sayHi 的 vtable 条目将与 exec 中的 Execute 函数具有相同的索引,因此,虽然源代码看起来会调用 sayHi,但实际上它会调用 exec。否则它可能会崩溃。

但任何事情都有可能发生。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。