在派生函数中指定void*参数

Specifying void* parameter in derived function

本文关键字:void 参数 派生 函数      更新时间:2023-10-16

我想做一些在Cpp中可能不可能做的事情,但我找不到关于这方面的专门帖子。

我想让一个派生类在虚拟函数上指定void*参数的类型。

我有一个名为interface的基类,它带有一个send函数。

// pure virtual
class Interface{
virtual bool Send(const void*)=0;
};
struct Packet{
DataType data;
};
class SpecificInterface{
bool Send(const DataType*);
}

有没有办法让这样的东西发挥作用?其目的是SpecificInterface::Send实现Interface::Send。允许SpecificInterface不是纯虚拟的,同时将void*限制为特定的数据包类型。

否则,我知道我可以取一个void*参数并static_cast将其转换为Packet*类型;但是,我不希望其他人发送无法转换为Packet*的指针类型。

如果不清楚,请告诉我

如果要重写virtual函数,参数的数量和类型必须与基类中的声明完全匹配。您必须使用:

class SpecificInterface{
bool Send(const void* ptr)
{
cont DataType* dataTypePtr = static_cast<const DataType*>(ptr);
// Now use dataTypePtr any way you wish
}
};

请注意,使用此类代码是危险的。如果ptr并没有真正指向DataType对象,那么程序将具有未定义的行为。

@RSahu当然是正确的。你仍然可以使用虚拟方法来做同样的事情:

class Interface {
virtual bool send(const void*) = 0;
};
struct Packet {
DataType data;
};
class SpecificInterface {
bool send(cont void*) override { 
send(static_cast<DataType*>(data));
}
bool send(cont DataType*); // code which actually does something
};

然而,我建议反对你的整个方法——这是非常不安全的,因为从来没有检查过类型的有效性!这是许多潜在错误的来源。通常情况下,你可以避免这样做。以下是一些你可以尝试的方法:

  1. std::any-一个不提供编译时类型安全性,但至少在运行时检查类型的类。您将有一个send(const std::any& data)虚拟函数,在其中您将调用std::any_cast<DataType>(data)来获得DataTypestd::any_cast<DataType>(&data)来获得DataType *

  2. 也许更好——奇怪的重复模板模式(CRTP(:

    template <typename T>
    class Interface {
    virtual bool send(T*) = 0;
    }; 
    class SpecificInterface : Interface<DataType> {
    bool send(cont DataType*) override;
    }