首页 > 解决方案 > 根据条件将类型转换为不同的类

问题描述

如果你需要这样的东西,你会怎么做?

假设一个函数 foo 接受一个 void*。

void foo(void* param);

在 foo 的函数定义中,根据条件,它将被类型转换为类 ABC 指针或类 DEF 指针。像这样的东西:

void foo(void* param) {
  if (condition) {
    ABC* abc = (ABC*) param;
  } else {
    DEF* abc = (DEF*) param;
  }

  // Irrespective of abc type, need to use abc quite a bit here. Such as abc->func1() etc.
  // So, abc should be made local to foo instead of the condition to use it later.
}

你一般如何解决这个问题?模板可能是一种方式。

标签: c++

解决方案


foo 的参数可以以某种方式制作,它是指向基类的指针,该基类具有接口类型的整数。

将参数转换为基类指针,您就可以获得接口类型。

然后你可以把它做成一个switch(interface_id)或类似的东西。

警告:代码未经测试,只是写在脑海中

例子:

class Base_Class
{
  public:
  uint16_t interface_id=0;
}

class Derived_1 : public Base_Class
{
  public:
   Derived_1() : Base_Class(), interface_id(1)
   {

   }
}

class Derived_2 : public Base_Class
{
  public:
   Derived_2() : Base_Class(), interface_id(2)
   {

   }
}

现在将 foo 的参数转换为基指针:

void foo(void* param) {
 if (!param)
   return;
 Base_Class * b = static_cast<Base_Class*>(param);
 uint16_t interfaceID = b->interface_id;
 switch (interfaceID)
 {
   case 1:
     Dervided_1* c1 = static_cast<Derived_1*>(b); break;
   case 2:
   //...
 }
}

在处理固定为使用 void 指针(回调等)的 C API 时,我经常使用这种方法。这可能不是最顺畅的方式,但对于很多人来说似乎很容易理解。这部分使其易于维护。

其他变体可能是动态转换基指针并检查结果。或者,如果您在派生类中覆盖它们,您可以以正确的方式使用虚拟方法。

请记住:如果您有一个 void 指针,则无法直接执行动态转换,因此请先转换为基指针,然后再执行动态转换。

这只是一个正确方向的提示,请不要将其用作“复制和粘贴”答案


推荐阅读