我可以使用函数指针调用虚拟析构函数吗?
Can I call a virtual destructor using a function pointer?
我有 class 可以保存指向对象的指针的数据。我希望以后能够手动调用它的析构函数,为此我需要将它的地址存储在一个变量中,但似乎禁止使用 constructor/destructor 的地址。有什么解决办法吗?
struct Data {
union {
long i;
float f;
void* data_ptr;
} _data;
std::type_index _typeIndex;
void (*_destructor_ptr)();
template<typename T>
void Init() {
if constexpr (std::is_integral<T>::value) {
//
}
else if constexpr (std::is_floating_point<T>::value) {
//
}
else {
_data.data_ptr = new T;
_typeIndex = std::type_index(typeid(T));
_destructor_ptr = &T::~T; // << -- can't do this
}
}
存储 lambda,适当转换:
void (*_destructor_ptr)(void *v);
// ...
_destructor_ptr = [](void* v) { delete static_cast<T*>(v); };
请注意,您必须为 v
传递 _data.data_ptr
。如果您打算存储普通函数指针,lambda 可能不会捕获或隐式引用 _data.data_ptr
.
如果您的编译器不支持 lambda,也有这个解决方案:
template<typename T>
struct DestructorHelper {
static void Destroy(void * v) {
delete static_cast<T*>(v);
}
};
并将其用作:
_destructor_ptr = &DestructorHelper<T>::Destroy;
我还会添加一个智能指针的解决方案:
template <class T>
struct DataPtrDeleter
{
void operator()(void * p) { delete (T*)p; }
}
std::shared_ptr<void*> data_ptr(new T, DataPtrDeleter<T>());
//or
std::unique_ptr<void*, DataPtrDeleter<T>> data_ptr(new T, DataPtrDeleter<T>());
我有 class 可以保存指向对象的指针的数据。我希望以后能够手动调用它的析构函数,为此我需要将它的地址存储在一个变量中,但似乎禁止使用 constructor/destructor 的地址。有什么解决办法吗?
struct Data {
union {
long i;
float f;
void* data_ptr;
} _data;
std::type_index _typeIndex;
void (*_destructor_ptr)();
template<typename T>
void Init() {
if constexpr (std::is_integral<T>::value) {
//
}
else if constexpr (std::is_floating_point<T>::value) {
//
}
else {
_data.data_ptr = new T;
_typeIndex = std::type_index(typeid(T));
_destructor_ptr = &T::~T; // << -- can't do this
}
}
存储 lambda,适当转换:
void (*_destructor_ptr)(void *v);
// ...
_destructor_ptr = [](void* v) { delete static_cast<T*>(v); };
请注意,您必须为 v
传递 _data.data_ptr
。如果您打算存储普通函数指针,lambda 可能不会捕获或隐式引用 _data.data_ptr
.
如果您的编译器不支持 lambda,也有这个解决方案:
template<typename T>
struct DestructorHelper {
static void Destroy(void * v) {
delete static_cast<T*>(v);
}
};
并将其用作:
_destructor_ptr = &DestructorHelper<T>::Destroy;
我还会添加一个智能指针的解决方案:
template <class T>
struct DataPtrDeleter
{
void operator()(void * p) { delete (T*)p; }
}
std::shared_ptr<void*> data_ptr(new T, DataPtrDeleter<T>());
//or
std::unique_ptr<void*, DataPtrDeleter<T>> data_ptr(new T, DataPtrDeleter<T>());