使用void指针从c函数调用模板成员

时间:2018-08-01 19:26:09

标签: c++ c templates void-pointers

我的c ++代码必须与基础c库一起使用。我有一个看起来像这样的c ++对象:

tail /var/log/apache2/error_log

稍后在我的C ++代码中,我执行以下操作:

template <typename T>
class MyClass
{
public:
  explicit MyClass(int x)
  : mVar(x)
  {
  }

private:
  int mVar;
};

c函数将指针“ p”保存在较大的c结构中。后来当大 c对象被破坏,它将调用删除处理程序。

  auto p = new MyClass<int>(10);

  call_c_lib_function((void*) p);

由于对象已被销毁,因此我需要释放分配的对象。 根据C ++规范,“ delete void_ptr”是未定义的,因为它不知道如何 调用适当的析构函数。如何在适当的位置调用delete 模板对象?

我能想到的一种解决方案是围绕MyClass指针创建包装器结构。

void
c_delete_handler(void* data)
{
  // data is holding the pointer value 'p' from above.
}

在调用call_c_lib_function之前,我将执行以下操作:

struct Wrapper {
  enum template_type {
    template_int,
    template_double,
    template_string,
    ...
  };

  int template_type;
  void* obj_ptr;
};

现在在删除处理程序中,我可以执行以下操作:

  auto p = new MyClass<int>(10);
  auto w = new Wrapper()
  w.template_type = Wrapper::template_int;
  w.obj_ptr = (void*) p;

  call_c_lib_function((void) w);

这是正确的方法吗?有更好的选择吗? 将不胜感激任何投入。谢谢。

1 个答案:

答案 0 :(得分:2)

如果可以的话,请使用基类,而不要使用Wrapper

class MyBase
{
   public:
      virtual ~MyBase() {};
};

template <typename T>
class MyClass : public MyBase
{
   public:
     explicit MyClass(int x) : mVar(x) {}

   private:
     int mVar;
};

然后

void c_delete_handler(void* data)
{
  Base* basePtr = reinterpret_cast<Base*>(data);
  delete basePtr;
}

这种方法无需跟踪MyClass是使用intdoublestd::string还是...实例化的。