C 将未知类型传递给虚拟函数
C++ passing unknown type to a virtual function
我正在用C 写作,我想将未知类型(仅在运行时间中知道)转到纯虚拟函数:
virtual void DoSomething(??? data);
其中 DoSomething
是派生类中纯虚拟函数的实现。
我计划使用模板,但是当事实证明虚拟函数,模板不能一起使用:C 类成员功能模板可以虚拟吗?
我想避免使用我传递给该功能的所有类的基类(类似于C#中的对象)。
预先感谢
您需要类型擦除。一个例子是通用boost::any
(C 17中的std::any
)。
virtual void DoSomething(boost::any const& data);
,然后每个子级都可以尝试 SAFE any_cast
以获取其期望的数据。
void DoSomething(boost::any const& data) {
auto p = any_cast<std::string>(&data);
if(p) {
// do something with the string pointer we extracted
}
}
,如果您寻求的行为范围更加限制,您当然可以推出自己的类型删除抽象。
如果您不想使用boost/c 17,请考虑从基类中派生'剂量米仪的参数,然后将动态铸造到正确的类对象。在这种情况下,您可以在运行时检查有效的指针。
class param{
public:
virtual ~param(){};
};
template <typename T>
struct specificParam:param{
specificParam(T p):param(p){}
T param;
};
class Foo
{
public:
virtual void doSomething(param* data) = 0;
};
template <typename T>
class Bar : public Foo
{
public:
virtual void doSomething(param* data){
specificParam<T> *p = dynamic_cast<specificParam<T> *>(data);
if (p != nullptr){
std::cout<<"Bar got:" << p->param << "n";
}
else {
std::cout<<"Bar: parameter type error.n";
}
}
};
int main(){
Bar<char> obj1;
Bar<int> obj2;
Bar<float> obj3;
specificParam<char> t1('a');
specificParam<int> t2(1);
specificParam<float> t3(2.2);
obj1.doSomething(&t1); //Bar got:a
obj2.doSomething(&t2); //Bar got:1
obj3.doSomething(&t3); //Bar got:2.2
// trying to access int object with float parameter
obj2.doSomething(&t3); //Bar: parameter type error.
}
最简单(但不安全!)的方法是使用void* pointer static cast
class Foo
{
public:
virtual void doSomething(void* data) = 0;
};
template <typename T>
class Bar:public Foo
{
public:
virtual void doSomething(void* data){
T* pData = static_cast<T*>(data);
std::cout<<"Bar1 got:" << *pData << "n";
}
};
int main(){
Bar<char> obj1;
Bar<int> obj2;
Bar<float> obj3;
char c = 'a';
int i = 1;
float f = 2.2;
obj1.doSomething(&c); // Bar1 got:a
obj2.doSomething(&i); // Bar1 got:1
obj3.doSomething(&f); // Bar1 got:2.2
//obj2.doSomething(&c); // Very bad!!!
}
type-erasure不是唯一的可能性。
您可能有兴趣使用访问者模式:以参数为std ::变体,并使用包含要实现的模板代码的lambda访问它:
virtual void doSomething(std::variant<int,float/*,...*/> data)
{
visit([=](auto v){/*...*/;},data);
}
类似的东西?:
class Foo
{
virtual ~Foo() = 0;
};
template <typename T>
class Bar : public Foo
{
T object;
}
...
virtual void DoSomething(Foo* data)
{
Bar<int>* temp = dynamic_cast<Bar<int>*>(data);
if (temp)
std::count<<temp->object;
}
相关文章:
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 用纯虚拟函数兜圈子
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 禁止子函数调用父级的抽象(或虚拟)函数
- 无法在子类中使用虚拟函数C++
- 无法在派生对象上运行虚拟函数
- 我可以调用从 main() 覆盖的虚拟函数吗?
- 在 C++ 中将函数获取和设置为虚拟函数
- 使用在堆栈上创建的对象调用虚拟函数
- 为什么在这种情况下不调用我的虚拟函数实现?
- 在C++中使虚拟函数私有化
- 模板继承类中的虚拟函数
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- doxygenc++虚拟函数和实现
- 如何从派生类函数中调用虚拟函数