在派生函数中指定 void* 参数
Specifying void* parameter in derived function
我想做一些在 Cpp 中可能做不到的事情,但是我找不到 post 关于这个的具体内容。
我想要派生的 class 指定虚函数上 void* 参数的类型。
我有一个基础 class 接口,带有发送功能。
// 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 中的声明完全匹配。您必须使用:
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
};
但是 - 我建议 反对 你的整个方法开始 - 它非常不安全,因为类型的有效性从未被检查过!它是许多潜在错误的来源。通常情况下,您可以避免这样做。以下是您可以尝试的一些方法:
std::any
- class 不提供编译时类型安全,但至少在 运行 时检查类型。你会有一个 send(const std::any& data)
虚函数,在它里面你会调用 std::any_cast<DataType>(data)
来获得 DataType
或 std::any_cast<DataType>(&data)
来获得 DataType *
.
可能更好 - Curiously-recurring template pattern (CRTP):
template <typename T>
class Interface {
virtual bool send(T*) = 0;
};
class SpecificInterface : Interface<DataType> {
bool send(cont DataType*) override;
}
我想做一些在 Cpp 中可能做不到的事情,但是我找不到 post 关于这个的具体内容。
我想要派生的 class 指定虚函数上 void* 参数的类型。
我有一个基础 class 接口,带有发送功能。
// 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 中的声明完全匹配。您必须使用:
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
};
但是 - 我建议 反对 你的整个方法开始 - 它非常不安全,因为类型的有效性从未被检查过!它是许多潜在错误的来源。通常情况下,您可以避免这样做。以下是您可以尝试的一些方法:
std::any
- class 不提供编译时类型安全,但至少在 运行 时检查类型。你会有一个send(const std::any& data)
虚函数,在它里面你会调用std::any_cast<DataType>(data)
来获得DataType
或std::any_cast<DataType>(&data)
来获得DataType *
.可能更好 - Curiously-recurring template pattern (CRTP):
template <typename T> class Interface { virtual bool send(T*) = 0; }; class SpecificInterface : Interface<DataType> { bool send(cont DataType*) override; }