i****h 发帖数: 321 | 1 非大牛,试着答一下。这题主要是要考非virtual destructor。
g点在这句
Var2 = (Base) *Var;
声明了*Var 是Base的,destructor又不是virtual,所以先要调用
Destructor : Base //4
然后调用其实际类型的destructor。
Destructor : Derived //5
从而又调用了一次Base的destructor
Destructor : Base //6
最后一行就不需要解释了。 |
|
w********p 发帖数: 948 | 2 问题继续, 包子继续
class Base
{
public:
Base(){ cout<<"Constructor: Base"<
~Base(){ cout<<"Destructor : Base"<
};
class Derived: public Base
{
public:
Derived(){ cout<<"Constructor: Derived"<
~Derived(){ cout<<"Destructor : Derived"<
};
int main()
{
Derived Var1;
Base Var2(Var1);
Derived Var3(Var1);
return 0;
}
output:
Constructor: Base
Constructor: Derived
Destructor : Derived
Destructor : Base
Destructor : Base
Destructor : Derived
Destructor : Base
请解释一下 |
|
a**********s 发帖数: 588 | 3 int main()
{
Derived Var1;
>>>> construct var1
>>>> Constructor: Base
>>>> Constructor: Derived
Base Var2(Var1);
Derived Var3(Var1);
>>>> The construction of above wont print anything
>>>> since the default copy constructs are done silently
return 0;
>>>> UPON RETURN <<<<
>>>> destruct var3
>>>> Destructor : Derived
>>>> Destructor : Base
>>>> destruct var2
Destructor : Base
>>>> destruct var1
Destructor : Derived
Destructor : Base
} |
|
f****4 发帖数: 1359 | 4 这里的“destructor出错不可以抛出异常”不是说c++语法禁止你这么做
而是在exception 抛出之后,正常代码的执行持续被打断,进入异常处理阶段
同时,所有的local 对象都要call destructor
c++异常处理同时只能处理1个异常
所以如果你允许在destructor抛出异常的话,就有可能在stack unwinding的过程中,
有2个异常————结果就是程序abort()
所以有“destructor出错不可以抛出异常”的说法 |
|
c****o 发帖数: 1280 | 5 Note: in a derived class, if your base class has a virtual destructor, your
own destructor is automatically virtual. You might need an explicit
destructor for other reasons, but there's no need to redeclare a destructor
simply to make sure it is virtual. No matter whether you declare it with the
virtual keyword, declare it without the virtual keyword, or don't declare
it at all, it's still virtual. |
|
w********p 发帖数: 948 | 6 【 以下文字转载自 Programming 讨论区 】
发信人: whitetulip (白色郁丁香), 信区: Programming
标 题: 问关于C++Destructor的问题
关键字: 'base class' 'destructor' 'case' 'assignment'
发信站: BBS 未名空间站 (Sat Nov 7 01:06:59 2009, 美东)
#include
using namespace std;
class Base
{
public:
Base(){ cout<<"Constructor: Base"<
~Base(){ cout<<"Destructor : Base"<
};
class Derived: public Base
{
//Doing a lot of jobs by extending the functionality
public:
Derived(){ cout<<"Constructor: Derived"<
~Derived() |
|
a**********s 发帖数: 588 | 7 int main()
{
Derived *Var = new Derived();
>>>> 这个语句, 分别调用基类和派生类的构造函数, 于是
>>>> Constructor: Base //1
>>>> Constructor: Derived //2
Base Var2;
>>>> 这个语句, 调用基类构造函数, 于是
>>>> Constructor: Base //3
Var2 = (Base) *Var;
>>>> 这个语句有一丝丝复杂, 等号右边产生一个临时Base类型的变量,
>>>> 调用Base类的"拷贝构造函数" Base(const Base&), 但是
>>>> 这个你没有定义, 所以什么都没有打印出来
>>>> 临时变量消灭的时候, 调用析构函数, 于是:
Destructor : Base //4
delete Var;
>>>> 这个比较简单
>>>> Destructor : Derived //5
>>>> Destructor : Base //6
return 0;
>>>> 这个也比较简单, 因为Var1的生命周期随着函数的返回结束
>>> |
|
p*****a 发帖数: 147 | 8 关于virtual destructor的实现:
也是用vtable实现的吗?
base class 和derived class 的virtual destructor 是不会override each other的
吧,所以在delete base class pointer to derived class object时,两个
destructor都会被call,
这样说对不对? |
|
m*****e 发帖数: 4193 | 9 My guess is that private/public protection is effective only at compile time
, but virtual functions are run-time bound. So the code compiles, because
you are invoking the destructor through A's public destructor. But at run-
time it's actually B's destructor that gets invoked. |
|
y**b 发帖数: 10166 | 10 Effective C++ Third Edition 55 Specific Ways to Improve Your Programs
item 7:
Polymorphic base classes should declare virtual destructors. If a class has
any virtual functions, it should have a virtual destructor.
Classes not designed to be base classes or not designed to be used polymorph
ically should not declare virtual destructors.
简单说,虚函数增加了vptr. |
|
a**********s 发帖数: 588 | 11 你快点到了, 但是差了那么一点点---没有解释为什么调用destructor, 却看不到调用
constructor ^_^
而且说的调用destructor的理由也好像怪怪的, 和virtual一点关系都没 :) |
|
r****o 发帖数: 1950 | 12 多谢多谢,我C++比较弱。
你的意思是不是说如果destructor 抛出一个异常(第一个),所有的local 对象都要
call destructor, 这其中又可能出错,可能会抛出第二个异常,这样程序就不知道该
处理哪个异常了。
再请问一下,为什么constructor出错又可以抛出异常呢? |
|
e**c 发帖数: 95 | 13 Can implict system destructor do everything? When do we need explictly to define our own destructor?
FYI. |
|
c**********e 发帖数: 2007 | 14 Which one of the following statements is correct?
a) A virtual destructor is required in any class with pure virtual member
functions.
b) A base class must have a virtual destructor when someone uses a base
class pointer to delete a derived class object. |
|
l*****a 发帖数: 14598 | 15 简单说,virtual destructor不是非有不可
什么时候定义比较合适effective c++上写了
大家去看看吧
因为没必要非用base class pointer to delete derive class object
so ,virtual destructor is not a must |
|
d*******u 发帖数: 186 | 16 If you have some resources which have to be released in the base class,
the destructor has to be defined as virtual, otherwise only the destructor
of the inherit be called. |
|
w*********t 发帖数: 319 | 17 Could you tell me any situation not to use virtual destructor? Usually I use
virtual destructor in derived classes.
This might related embedded C++ software.
Thanks. |
|
c***d 发帖数: 996 | 18 ☆─────────────────────────────────────☆
marriott (marriott) 于 (Sun Sep 23 16:45:59 2007) 提到:
好像记得这里讨论过说virtual的是错的。
但是
http://www.codersource.net/published/view/325/virtual_functions_in.aspx
说一定要virtual才行?
☆─────────────────────────────────────☆
thrust (Thrust Jaeina) 于 (Sun Sep 23 16:48:00 2007) 提到:
很明显,你的记忆有问题
destructor不是一定要virtual,但是不virtual常常是错的
☆─────────────────────────────────────☆
OldMonk (old monk) 于 (Sun Sep 23 16:49:38 2007) 提到:
that article didnot say destructor must |
|
b***y 发帖数: 2799 | 19 ☆─────────────────────────────────────☆
gebitan (job, job) 于 (Thu Sep 1 17:08:27 2005) 提到:
I got an question like this:
class B{public: virtual ~B()=0;};
class D : public B{};
Is there anything wrong?
The answer is nothing wrong. But I can not understand why put destructor as
pure virtual function.
☆─────────────────────────────────────☆
wy (Parry Otter) 于 (Thu Sep 1 17:25:38 2005) 提到:
so that its concrete derive must implement a destructor ya. ft
☆────────────────────────────────── |
|
w********p 发帖数: 948 | 20 #include
using namespace std;
class Base
{
public:
Base(){ cout<<"Constructor: Base"<
~Base(){ cout<<"Destructor : Base"<
};
class Derived: public Base
{
//Doing a lot of jobs by extending the functionality
public:
Derived(){ cout<<"Constructor: Derived"<
~Derived(){ cout<<"Destructor : Derived"<
};
int main()
{
Derived *Var = new Derived();
Base Var2;
Var2 = (Base) *Var;
delete Var;
return 0;
}
output:
Constructor: Base //1
Co |
|
h**k 发帖数: 3368 | 21 是在执行子类的destructor之前调用,还是执行之后调用? |
|
c**********e 发帖数: 2007 | 22 1. What are the disadvantages of any of declaring a destructor virtual?
2. Do you think that C++ should simply default to making all destructor
virtual? |
|
g*******y 发帖数: 1930 | 23 可惜来晚了,被牛人抢了先,没吃到包子。。。
唯一比较tricky的地方就是那个static_cast的地方有临时的base object,死掉
的时候会调用一个destructor |
|
r****o 发帖数: 1950 | 24 看了一些资料还是没搞明白为什么C++的constructor出错可以抛出异常,
而destructor出错不可以抛出异常。
有知道的能说说吗? |
|
f****4 发帖数: 1359 | 25 "constructor出错又可以抛出异常"
c++其实没有禁止任何函数抛出异常(包括destructor也能抛出异常)
constructor抛出异常,你try catch处理一下就好了;和其他抛出异常的函数一样
你把effective c++和more effective c++看2遍,很多细节就都明白了 |
|
C******a 发帖数: 32 | 26 You can throw an exception inside constructor, but then the destructor won't
be called. So your data members need to release their own resources; for
example don't allocate memery to a raw pointer member, instead use a shared_
ptr. |
|
f****4 发帖数: 1359 | 27 有几点说明一下
第一,如果有 exception在constructor里面被抛出,那么当前对象并没有创建成功,也就没有所谓的destructor可以调用
第二, 在constructor里面allocate 资源的时候,用smart ptr,不要用raw pointer; smart ptr能保证到出异常为止,所有正常分配的资源自动释放
第三,在constructor里面发生异常的时候,分配给当前object的memeory不会泄露;这是有compiler自动完成的,可以理解成,一旦constructor fail,异常处理程序会自动释放分配给当前object的memeory
't
shared_ |
|
r****o 发帖数: 1950 | 28 多谢。
,也就没有所谓的destructor可以调用
; smart ptr能保证到出异常为止,所有正常分配的资源自动释放
这是有compiler自动完成的,可以理解成,一旦constructor fail,异常处理程序会自
动释放分配给当前object的memeory |
|
i****h 发帖数: 321 | 29 我不太明白第二点。你说的是allocator自动用了smart ptr还是我们必须这样写?
谢谢。
,也就没有
所谓的destructor可以调用
; smart
ptr能保证到出异常为止,所有正常分配的资源自动释放
这是有
compiler自动完成的,可以理解成,一旦constructor fail,异常处理程序会自动释放
分配给当前
object的memeory |
|
B*M 发帖数: 1340 | 30 destructor 被调用可能就是异常引起的,
如果再继续抛出异常,也不会得到正确的处理, |
|
s********a 发帖数: 1447 | 31 第二, 在constructor里面allocate 资源的时候,用smart ptr,不要用raw pointer;
smart ptr能保证到出异常为止,所有正常分配的资源自动释放
恩? 我怎么觉得应该是 auto-ptr
,也就没有所谓的destructor可以调用
; smart ptr能保证到出异常为止,所有正常分配的资源自动释放
这是有compiler自动完成的,可以理解成,一旦constructor fail,异常处理程序会自
动释放分配给当前object的memeory |
|
l*****a 发帖数: 559 | 32 a不一定,虽然推荐用virtual destructor. |
|
a***c 发帖数: 2443 | 33 the only time you want to call the destructor explicitly is if you use '
placement new' for the purpose of specifying the particular memory location
of the created object, in which case you're responsible for the clean-up. |
|
c********s 发帖数: 1024 | 34 can't agree more...
your
destructor
the
declare |
|
f****4 发帖数: 1359 | 35 virtual destructor就是干这个活的
下次,你可以自己写个代码检验一下
#include
class A{
public:
virtual ~A()
{
printf("A::~A\n");
}
};
class B: public A
{
public:
virtual ~B()
{
printf("B::~B\n");
}
};
int main()
{
A *p = new B();
delete p;
printf("=====\n");
B b;
A &a = b;
} |
|
Z**********4 发帖数: 528 | 36 vitual destructor 是virtual function 的一种吧。。 |
|
b*****c 发帖数: 1103 | 37 destructor最好宣告成virtual,否则会很麻烦 |
|
e*********l 发帖数: 136 | 38 Base *basePtr = new Derived()
~basePtr()
destructor如果不是virtual的话就出问题了 |
|
H***e 发帖数: 476 | 39 啥意思
有virtual function的话,不是得virtual destructor才可以有效clean
肯定得在vtable里面 |
|
|
d**********x 发帖数: 4083 | 41 要看你获得的是什么资源
如果只是内存,好说,程序退出什么都没了
如果有系统资源需要释放的,就要有destructor,而且要想办法在程序退出时析构。 |
|
j******2 发帖数: 362 | 42 那只有另定义一个destroy()啥的,在destructor里delete 要死循环啊。 |
|
l*********u 发帖数: 19053 | 43 查了下,析构函数原来是destructor,谁翻译的呀? :) |
|
|
m******t 发帖数: 2416 | 45
(I have some vague memory this came up here before.)
With the GC in place, no longer is the destruction of an instance
predictable to the programmer. So any timing-sensitive "resource management"
can't be done in a destructor (or "finalizer" as in Java) anyway. Some kind
of non-standard destroy/release/shutdown method would have to be defined on
a per-class basis.
I see it more as some price paid for all the benefits of GC brings, but not
a loss of any pattern - as long as a pattern can be easi |
|
l*********s 发帖数: 5409 | 46 Say, to implement a directed map of G(vertex,arcs) with adjacency lists.
Naturally, one would like to deleted all the edges associated with a given
node when trying to delete it.
Without explicit call of destructor, how to do this in Java? |
|
P********e 发帖数: 2610 | 47 你前面temp能是create on heap
private destructor 能保证instance ONLY on HEAP
如果要STACK的话,overload operator new/delete as private, 其实严谨一点
malloc, alloc, realloc都要overload
你的方法是在heap上 |
|
mw 发帖数: 525 | 48 比如说
main(){
class a;
class b;
..
..
..
}
最后结束了,a和b哪个的destructor先被叫? |
|
t****t 发帖数: 6806 | 49 这个顺序当然可以依赖, 离开scope的时候, destructor的顺序总是和constructor相反
的. |
|
z**k 发帖数: 629 | 50 楼主的示例似乎有错,是不是想说这样:
class a
{
...
};
class b
{
...
};
main(){
a a1;
b b1;
..
..
..
}
那么在main函数的"}"处,b1的destructor先被调用,然后再调a1的析构函数. |
|