建议解决缺少虚拟析构函数的问题 [英] Proposed work-around for missing virtual destructors
问题描述
我在我的博客上发布了一个特殊的指针类,用于继承
基类而不使用虚拟析构函数。我想知道是否还有其他类似的工作,以及我提出的
方法是否有任何问题。提前致谢!
请参阅 http ://www.artima.com/weblogs/viewpo ...?thread = 107587
对于那些只想要代码的人:
>
模板< typename target_type>
class base_class_ptr {
public:
//转发声明
模板< class T>
结构函数;
模板< class T>
base_class_ptr(T * x)
:m_a(x),m_t(& functions< T> :: table)
{}
target_type * operator->(){
返回static_cast< target_type *>(m_a);
}
void删除(){
m_t- >删除(m_a);
m_a = NULL;
}
//函数表类型
struct table {
void(* Delete)(void *);
};
//对于给定的引用类型T,生成函数
//函数t能够和桌子的静态实例。
模板< class T>
结构函数
{
静态typename base_class_ptr< target_type> :: table table;
static void删除(void * p){
删除static_cast< T *>(p);
}
};
私人:
void * m_a;
table * m_t; < br $>
};
模板< typename target_T>
模板< class T>
typename base_class_ptr< target_T> :: table
base_class_ptr< target_T> :: functions< T> :: table = {
& base_class_ptr< target_T> :: template functions< T>: :删除
};
-
Christopher Diggins
面向对象的模板库(OOTL) )
http://www.ootl.org
I posted to my blog a special pointer class work-around for inheriting from
base classes without virtual destructors. I was wondering if there is any
other similar work, and whether there are any problems with my proposed
approach. Thanks in advance!
See http://www.artima.com/weblogs/viewpo...?thread=107587
For those who just want the code:
template<typename target_type>
class base_class_ptr {
public:
// forward declarations
template <class T>
struct functions;
template <class T>
base_class_ptr(T* x)
: m_a(x), m_t(&functions<T>::table)
{}
target_type* operator->() {
return static_cast<target_type*>(m_a);
}
void Delete() {
m_t->Delete(m_a);
m_a = NULL;
}
// Function table type
struct table {
void (*Delete)(void*);
};
// For a given referenced type T, generates functions for the
// function table and a static instance of the table.
template<class T>
struct functions
{
static typename base_class_ptr<target_type>::table table;
static void Delete(void* p) {
delete static_cast<T*>(p);
}
};
private:
void* m_a;
table* m_t;
};
template<typename target_T>
template<class T>
typename base_class_ptr<target_T>::table
base_class_ptr<target_T>::functions<T>::table = {
&base_class_ptr<target_T>::template functions<T>::Delete
};
--
Christopher Diggins
Object Oriented Template Library (OOTL)
http://www.ootl.org
推荐答案
christopher diggins写道:
christopher diggins wrote:
我在我的博客上发布了一个特殊的指针类,用于从没有虚拟析构函数的基类继承。我想知道是否还有其他类似的工作,以及我提出的方法是否有任何问题。
I posted to my blog a special pointer class work-around for inheriting from
base classes without virtual destructors. I was wondering if there is any
other similar work, and whether there are any problems with my proposed
approach.
太多无效* '的。结果是这不是类型安全的:
struct T {};
struct U {};
base_class_ptr< T>((U *)0);
该代码并未强制执行U来自
的隐含要求T.可以通过将指针存储为T *而不是void *来固定,
按原样(通常)在TR1的shared_ptr中完成。
我也会给这个帖子一个不同的标题:逃避设计决策:
删除从没有虚拟析构函数的类派生的类型。在
之后,通常有一个很好的理由不提供虚拟析构函数。
-
Pete Becker
Dinkumware,Ltd。( http://www.dinkumware .com )
christopher diggins写道:
christopher diggins wrote:
我在我的博客上发布了一个特殊的指针类解决方案
从没有虚拟析构函数的基类继承。我想知道是否有
任何其他类似的工作,以及我的
提议的方法是否有任何问题。提前致谢!
请参阅 http:// www .artima.com / weblogs / viewpo ...?thread = 107587
对于那些只想要代码的人:
模板< typename target_type>
class base_class_ptr {
public:
//转发声明
模板< class T>
结构函数;
模板< class T>
base_class_ptr(T * x)
:m_a(x),m_t(& functions< T> :: table)
{}
target_type * operator->(){
return static_cast< target_type *>(m_a);
}
void Delete(){
m_t->删除(m_a);
m_a = NULL;
}
//函数表类型
struct table {
void(* Delete)(void *);
};
//对于给定的引用类型T ,为
// fu生成函数表格和表格的静态实例。
模板< class T>
结构函数
{static typename base_class_ptr< target_type> :: table table;
static void删除(void * p){
删除static_cast< T *>(p);
}
};
私人:
void * m_a;
table * m_t;
};
模板< typename target_T>
模板< class T>
typename base_class_ptr< target_T> :: table
base_class_ptr< target_T> :: functions< T> :: table = {
& base_class_ptr< target_T> :: template functions< T> :: Delete
};
- -
Christopher Diggins
面向对象的模板库(OOTL)
http: //www.ootl.org
I posted to my blog a special pointer class work-around for inheriting from base classes without virtual destructors. I was wondering if there is any other similar work, and whether there are any problems with my proposed approach. Thanks in advance!
See http://www.artima.com/weblogs/viewpo...?thread=107587
For those who just want the code:
template<typename target_type>
class base_class_ptr {
public:
// forward declarations
template <class T>
struct functions;
template <class T>
base_class_ptr(T* x)
: m_a(x), m_t(&functions<T>::table)
{}
target_type* operator->() {
return static_cast<target_type*>(m_a);
}
void Delete() {
m_t->Delete(m_a);
m_a = NULL;
}
// Function table type
struct table {
void (*Delete)(void*);
};
// For a given referenced type T, generates functions for the
// function table and a static instance of the table.
template<class T>
struct functions
{
static typename base_class_ptr<target_type>::table table;
static void Delete(void* p) {
delete static_cast<T*>(p);
}
};
private:
void* m_a;
table* m_t;
};
template<typename target_T>
template<class T>
typename base_class_ptr<target_T>::table
base_class_ptr<target_T>::functions<T>::table = {
&base_class_ptr<target_T>::template functions<T>::Delete
};
--
Christopher Diggins
Object Oriented Template Library (OOTL)
http://www.ootl.org
我会避免使用void。
以下类是一种更安全的解决方法,并且这是类型安全的。
模板< typename base_type>
class base_class_ptr
{
class BaseContainer {
public:
virtual~BaseContainer(){}
};
template< typename derive_type>
class容器:public BaseContainer {
derive_type * m_derive_ptr;
public:
Container(derive_type * derive_obj):m_derive_ptr(derive_obj){}
~Container(){delete m_derive_ptr;}
};
public:
模板< typename derive_type>
base_class_ptr(derive_type * derive_obj)
:m_base_ptr(derive_obj),m_BaseContainer(新
容器< derive_type>(derive_obj)){}
~base_class_ptr(){delete m_BaseContainer;}
base_type * operator->(){return m_base_ptr;}
私人:
base_type * m_base_ptr;
BaseContainer * m_BaseContainer;
};
示例用法:
void SomeFunction()
{
base_class_ptr< MyBaseClass> ptr_a(new MyDerivedClass_a);
ptr_a-> TestFunct();
base_class_ptr< MyBaseClass> ptr_b(new MyDerivedClass_b);
ptr_b-> TestFunct();
}
I would avoid using void.
The following class is a safer workaround method, and it''s type safe.
template<typename base_type>
class base_class_ptr
{
class BaseContainer{
public:
virtual ~BaseContainer(){}
};
template<typename derive_type>
class Container : public BaseContainer{
derive_type *m_derive_ptr;
public:
Container(derive_type* derive_obj):m_derive_ptr(derive_obj){}
~Container(){delete m_derive_ptr;}
};
public:
template<typename derive_type>
base_class_ptr(derive_type* derive_obj)
:m_base_ptr(derive_obj), m_BaseContainer(new
Container<derive_type>(derive_obj)){}
~base_class_ptr(){delete m_BaseContainer;}
base_type* operator->() {return m_base_ptr;}
private:
base_type *m_base_ptr;
BaseContainer *m_BaseContainer;
};
Example usage:
void SomeFunction()
{
base_class_ptr<MyBaseClass> ptr_a(new MyDerivedClass_a);
ptr_a->TestFunct();
base_class_ptr<MyBaseClass> ptr_b(new MyDerivedClass_b);
ptr_b->TestFunct();
}
christopher diggins写道:
christopher diggins wrote:
在C ++中,通常建议公开继承具有虚拟析构函数的类,以避免可能的内存泄漏。
内存泄漏但内存损坏。一般来说未定义的行为。
我在我的博客上发布了一个特殊的指针类,可以从没有虚拟析构函数的基类继承
。我想知道是否有
任何其他类似的工作,以及我的
提议的方法是否有任何问题。提前致谢!
请参阅 http:// www .artima.com / weblogs / viewpo ...?thread = 107587
对于那些只想要代码的人:
模板< typename target_type>
class base_class_ptr {
[模板大惊小怪]
void * m_a;
table * m_t;
};
模板< typename target_T>
模板<类T>
typename base_class_ptr< target_T> :: table
base_class_ptr< target_T> :: functions< T> :: table = {
& base_class_ptr< target_T> ::模板函数< T> ::删除
};
It is commonly recommended in C++ to publicly inherit from
classes which have virtual destructors, to avoid possible memory
leaks.
Not memory leaks but memory corruption. Undefined behavior in general.
I posted to my blog a special pointer class work-around for inheriting from base classes without virtual destructors. I was wondering if there is any other similar work, and whether there are any problems with my proposed approach. Thanks in advance!
See http://www.artima.com/weblogs/viewpo...?thread=107587
For those who just want the code:
template<typename target_type>
class base_class_ptr {
[template fuss snipped]
void* m_a;
table* m_t;
};
template<typename target_T>
template<class T>
typename base_class_ptr<target_T>::table
base_class_ptr<target_T>::functions<T>::table = {
&base_class_ptr<target_T>::template functions<T>::Delete
};
您替换内置的vtable与你自己的外部,手写,
''复杂''vtable。是什么原因?当然不是表演。
安倍
You replace the built-in vtable with you own external, hand-written,
''complicated'' vtable. For what reason? Certainly not performance.
Abe
这篇关于建议解决缺少虚拟析构函数的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!