簡體   English   中英

使用void指針從c函數調用模板成員

[英]Invoke a templated member from a c-function using void pointer

我的c ++代碼必須與基礎c庫一起使用。 我有一個看起來像這樣的c ++對象:

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

private:
  int mVar;
};

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

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

  call_c_lib_function((void*) p);

c函數將指針“ p”保存在較大的c結構中。 稍后,當大型c對象被銷毀時,它將調用delete處理程序。

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

由於對象已被銷毀,因此我需要釋放分配的對象。 根據c ++規范,“ delete void_ptr”是未定義的,因為它不知道如何調用適當的析構函數。 如何在適當的模板對象上調用delete?

我能想到的一種解決方案是圍繞MyClass指針創建包裝器結構。

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

  int template_type;
  void* obj_ptr;
};

在調用call_c_lib_function之前,我將執行以下操作:

  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);

現在在刪除處理程序中,我可以執行以下操作:

void
c_delete_handler(void* data)
{
  Wrapper* w = (Wrapper*) data;

  switch (w->template_type) {
    case Wrapper::template_int:
      delete (MyClass<int>*) w->obj_ptr;
      break;

    case Wrapper::template_double:
      delete (MyClass<double>*) w->obj_ptr;
      break;
    ...
  }
}

這是正確的方法嗎? 有更好的選擇嗎? 將不勝感激任何投入。 謝謝。

如果可以的話,請使用基類,而不要使用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;
}

這種方法消除了跟蹤使用intdoublestd::string或...實例化MyClass的需要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM