虚拟析构函数? [英] virtual destructor?

查看:154
本文介绍了虚拟析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

任何人都可以帮我解决这些相当简单的问题。


1)虚拟析构函数有什么意义 - 我听说过对于基础课来说,这是一件好事

,但这样做的优点和缺点是什么呢?

/或者不是这样的情况?


2)在下面的例子中,代码部分BD和DD *是否*将要调用

?我认为他们都会一直这样,但是在所有情况下,这保证超出所有赔率吗? (当我说是保证 - 我的意思是他们都会得到

在某个时刻叫* *,不一定按照任何特定的顺序)


B级

{

B(){}

virtual~B(){//代码BD //}

};

D级:公共B

{

D(){}

虚拟~D( ){//代码DD //}

};

Hello,
Can anyone help me with these fairly simple questions.

1) What is the point in virtual destructors - I''ve heard it''s a good thing
for base-classes, but what are the advantages and disadvantages of doing so
/ or not as the case maybe?

2) In the following example, are code sections BD and DD *both* going to get
called? I assume they both always will, but is this guaranteed beyond all
odds in all cases? (When I say is it guaranteed - I mean will they both get
called *at some point*, not necessarily in any particular order)

class B
{
B() {}
virtual ~B() {// code BD //}
};
class D : public B
{
D() {}
virtual ~D() {//code DD//}
};

推荐答案

答案1最好说明例如:


struct base

{

base(){}

~base( ){}

};


派生类

{

int * p;

public:

derived(){p = new int [100]; }

~ derived(){delete [] p; }

}


int main()

{

base * b = new derived( );

//用b做一些东西

删除b; //哎呀!

}


现在当b被删除(标记为oops的行)时,~base()被调用但不是

~derived(),因此派生类中p指向的空间不会被释放,并且你有内存泄漏。


如果你让析构函数变为虚拟,那么〜derived()会被正常调用。


我知道这样做的唯一缺点是虚拟的开销

函数调用一般;基本上,通过双重

间接指针而不是直接调用,以及设置

的开销,如果析构函数是唯一的话,根本就可以使用虚函数br />
虚拟的东西。 (对于第一个虚拟函数来说,有相当数量的基本开销,而且每增加一个虚拟函数需要很少的费用。)

The answer 1 is best illustrated by example:

struct base
{
base() {}
~base() {}
};

class derived
{
int *p;
public:
derived() { p = new int[100]; }
~derived() { delete[] p; }
}

int main()
{
base *b = new derived();
// do some stuff with b
delete b; // oops!
}

Now when b is deleted (the line marked oops), ~base() is called but not
~derived(), so the space pointed to by p in the derived class isn''t
deallocated, and you have a memory leak.

If you make the destructor virtual, ~derived() is called as normal.

The only downside I know of to doing this is the overhead of a virtual
function call in general; that is essentially, calling through a double
indirection pointer instead of directly, and the overhead of setting
things up to use virtual functions at all if the destructor is the only
virtual thing. (There is a fair amount of "base overhead" for having
the first virtual function, plus a small cost for each additional one.)


2005-03-20,Bonj< a@b.com>写道:
On 2005-03-20, Bonj <a@b.com> wrote:
你好,
任何人都可以帮我解决这些相当简单的问题。

1)虚拟析构函数有什么意义 - 我听说过对于基础班来说,这是一件好事,但这样做的优点和缺点是什么呢?或者不是这样的情况?


任何你打算多态地用作基类的类(任何一个

具有虚函数的类)都应该有一个虚析构函数。
http://www.parashift。 com / c ++ - faq-lit .... html#faq-20.7

2)在下面的例子中,代码部分BD和DD *都*将获得
打电话?


在这两个例子中,是的:


void f(){

D x;

//〜D(); ~B();

}


void g(){

B * x =新D;

删除x; //〜D(); ~B();

}

我认为他们两者都会,但是在所有情况下都保证超出所有赔率?


在所有合理的例子中,排除明显的内存泄漏。

(当我说保证时 - 我的意思是他们都会被称为* / *在某些时候*,不一定按任何特定顺序)
Hello,
Can anyone help me with these fairly simple questions.

1) What is the point in virtual destructors - I''ve heard it''s a good thing
for base-classes, but what are the advantages and disadvantages of doing so
/ or not as the case maybe?
Any class that you intend to use polymorphically as a base class (any class that
has virtual functions) should have a virtual destructor.
http://www.parashift.com/c++-faq-lit....html#faq-20.7
2) In the following example, are code sections BD and DD *both* going to get
called?
In both of these examples, yes:

void f(){
D x;
// ~D(); ~B();
}

void g() {
B* x = new D;
delete x; // ~D(); ~B();
}
I assume they both always will, but is this guaranteed beyond all
odds in all cases?
In all reasonable examples, excluding obvious memory leaks.
(When I say is it guaranteed - I mean will they both get
called *at some point*, not necessarily in any particular order)




派生类析构函数总是首先被调用。它按照这个顺序发生是很重要的,因为派生类析构函数可能需要使用基类对象所拥有的资源。


干杯,

-

Donovan Rebbechi
http://pegasus.rutgers.edu/~elflord/


好的,谢谢 - 看看内联......


" Evan" < EV **** @ gmail.com>在消息中写道

news:11 ********************** @ g14g2000cwa.googlegr oups.com ...
ok, thanks - see inline...

"Evan" <ev****@gmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
答案1最好用例子说明:

struct base
{
base(){}
~base(){}
base'')
{
int * p;
public:
derived(){p = new int [100]; }
〜derived(){delete [] p; }

int main()
{* base * b = new derived();
//用b做一些东西删除b; //哎呀!

现在当b被删除(标记为oops的行)时,~base()被调用但不是
~derived(),所以空间指向派生类中的p不被取消分配,并且你有内存泄漏。


ok,所以我认为确保所有*基类的析构函数都是

方式

up the up连锁起火,我需要让它们变得虚拟(因此回答我的第二个问题还是b $ b问题......)


但这引发了另一个我正在思考的问题,我没有问过:

让我们考虑你的代码修改为''virtual~base()''而不是

只是''〜基础()''。当你执行''删除b''时,base'的析构函数会被触发,以及

派生','/ b $ b因为它是虚拟的。这就是我们想要的。但是我的另一个问题是 - 当你用

做什么

''删除b''时,删除怎么知道它实际上正在删除
的实例
a''派生'',

而不是''base''的实例 - 因为''b''指向''base''

(即使它是实际派生的
)。我希望你能告诉我的是,当

''new''运行时,

有关实际类型大小的信息实例化

(''衍生'')在一些隐藏的内存中存储了
,以便删除可以是智能的并删除

右边数量

的内存,无论它是什么类型的指针。你可以为我澄清一下这个

吗?
如果你让析构函数变为虚拟,那么〜derived()会被正常调用。

唯一我知道这样做的缺点是一般虚拟
函数调用的开销;基本上,通过双重
间接指针而不是直接调用,以及如果析构函数是唯一的虚拟东西,设置
事情的开销根本就是使用虚函数。 (对于第一个虚拟功能,有相当数量的基本开销,另外每个额外的虚拟功能需要很少的费用。)
The answer 1 is best illustrated by example:

struct base
{
base() {}
~base() {}
};

class derived //(presuming you meant to put '' class derived : public
base'' )
{
int *p;
public:
derived() { p = new int[100]; }
~derived() { delete[] p; }
}

int main()
{
base *b = new derived();
// do some stuff with b
delete b; // oops!
}

Now when b is deleted (the line marked oops), ~base() is called but not
~derived(), so the space pointed to by p in the derived class isn''t
deallocated, and you have a memory leak.
ok, so I take it that to make sure *all* destructors of base classes all the
way
up the chain fire, I need to make them virtual (thus answering my second
question aswell...?)

But this raises another question I was pondering on, that I didn''t ask:
Let''s consider your code amended to have ''virtual ~base()'' rather than
just ''~base()''. When you do ''delete b'', base''s destructor fires aswell as
derived''s,
because it''s virtual. This is what we want. But my other question is - when
you do
''delete b'', how does delete know that it''s actually deleting an instance of
a ''derived'',
rather than an instance of a ''base'' - since ''b'' is a pointer to a ''base''
(even though it is
actually a derived). What I''m hoping you''re going to tell me is that when
''new'' runs,
information about the size of the actual type of class instantiated
(''derived'') is stored
in some hidden memory, in order that delete can be intelligent and delete
the right amount
of memory no matter what kind of pointer it is. Can you just clarify this
for me?

If you make the destructor virtual, ~derived() is called as normal.

The only downside I know of to doing this is the overhead of a virtual
function call in general; that is essentially, calling through a double
indirection pointer instead of directly, and the overhead of setting
things up to use virtual functions at all if the destructor is the only
virtual thing. (There is a fair amount of "base overhead" for having
the first virtual function, plus a small cost for each additional one.)



我很有信心如果这是这个班级图书馆中表现最差的表现

那么它还会比mfc快几英里。 ;-)


I''m sure that if this is the worst performance hit this class library
suffers then it''ll still be miles faster than mfc. ;-)


这篇关于虚拟析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆