使用 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 对象正在被销毁,它调用删除处理程序。
void
c_delete_handler(void* data)
{
// data is holding the pointer value 'p' from above.
}
由于对象正在被销毁,我需要释放分配的对象。
根据 c++ 规范,'delete void_ptr' 未定义,因为它不知道如何
调用适当的析构函数。如何在适当的位置调用删除
模板对象?
我能想到的一个解决方案是围绕我的 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,如果可以的话。
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
是否使用 int
、double
、std::string
或 ....[=17= 实例化的需要]
我的 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 对象正在被销毁,它调用删除处理程序。
void
c_delete_handler(void* data)
{
// data is holding the pointer value 'p' from above.
}
由于对象正在被销毁,我需要释放分配的对象。 根据 c++ 规范,'delete void_ptr' 未定义,因为它不知道如何 调用适当的析构函数。如何在适当的位置调用删除 模板对象?
我能想到的一个解决方案是围绕我的 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,如果可以的话。
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
是否使用 int
、double
、std::string
或 ....[=17= 实例化的需要]