首页 > 解决方案 > 将 void 动态转换为类型的安全方法?

问题描述

我的 C++ 有点生疏,我不记得标准中的所有内容。

我有一个void*. 在一个特定的函数中,它要么是继承 Alpha 的类,要么是继承 Beta 的类。两个基类都有虚函数。但是我似乎无法分辨哪个是哪个

class Alpha {
public:
    virtual void Speak() { printf("A"); }
};
class Beta {
public:
    virtual void Speak() { printf("B"); }
};
int main(){
    //BAD CODE WILL PRINT TWICE
    void *p = new Alpha;
    Alpha*a = dynamic_cast<Alpha*>((Alpha*)p);
    Beta*b = dynamic_cast<Beta*>((Beta*)p);
    if(a)
        a->Speak();
    if(b)
        b->Speak();
    return 0;
}

我如何确定哪个班级是哪个班级?此代码库中有 100 个类被转换为 void。他们中的大多数都继承了 5 个基类,但我并不急于找出答案。在使用动态转换之前,唯一的解决方案是从类似的东西继承class Dummy {public: virtual void NoOp(){}};并转换为 Dummy 吗?这安全吗?我希望有更好的解决方案,但我想不出别的。

标签: c++dynamic-cast

解决方案


对指针唯一能做的void*就是将它转换回与最初转换的指针完全相同的类型void*。做任何其他事情的行为是未定义的。

在你的情况下你可以做的是定义

class Base
{
    public:
    virtual ~Base() = default; // make me a polymorphic type and make 
                               // polymorphic delete safe at the same time.
};

并使其成为Alphaand的基类Beta。然后传递一个Base*指针而不是一个指针void*,然后直接将您dynamic_cast的 s 放在p.

进一步注意,如果您声明virtual void Speak() = 0;in Base,那么您的代码 inmain将变得简单

int main(){ 
    Base* p = new Alpha;
    p->Speak();
    delete p; // ToDo - have a look at std::unique_ptr
}

根据经验,任何类型的演员表都是不可取的。


推荐阅读