constructor and destructor

 <ctor-dtor-name> ::= C1   # complete object constructor
                 ::= C2   # base object constructor
                 ::= C3   # complete object allocating constructor
                 ::= D0   # deleting destructor
                 ::= D1   # complete object destructor
                 ::= D2   # base object destructor

 

•The "complete object constructor". It additionally constructs virtual base classes.
•The "base object constructor". It creates the object itself, as well as data members and non-virtual base classes.
•The "allocating object constructor". It does everything the complete object constructor does, plus it calls operator new to actually allocate the memory... but apparently this is not usually seen.
•D2 is the "base object destructor". It destroys the object itself, as well as data members and non-virtual base classes.
•D1 is the "complete object destructor". It additionally destroys virtual base classes.
•D0 is the "deleting object destructor". It does everything the complete object destructor does, plus it calls operator delete to actually free the memory.

 

There are usually two variants of the constructor (not-in-charge / in-charge) and three of the destructor (not-in-charge / in-charge / in-charge deleting).

The not-in-charge ctor and dtor are used when handling an object of a class that inherits from another class using the virtual keyword, when the object is not the complete object (so the current object is "not in charge" of constructing or destructing the virtual base object). This ctor receives a pointer to the virtual base object and stores it.

The in-charge ctor and dtors are for all the other cases, i.e. if there is no virtual inheritance involved; if the class has a virtual destructor, the in-charge deleting dtor pointer goes into the vtable slot, while a scope that knows the dynamic type of the object (i.e. for objects with automatic or static storage duration) will use the in-charge dtor (because this memory should not be freed).

Code example:

struct foo {     foo(int);     virtual ~foo(void);     int bar; };  struct baz : virtual foo {     baz(void);     virtual ~baz(void); };  struct quux : baz {     quux(void);     virtual ~quux(void); };  foo::foo(int i) { bar = i; } foo::~foo(void) { return; }  baz::baz(void) : foo(1) { return; } baz::~baz(void) { return; }  quux::quux(void) : foo(2), baz() { return; } quux::~quux(void) { return; }  baz b1; std::auto_ptr<foo> b2(new baz); quux q1; std::auto_ptr<foo> q2(new quux); Results:

•The dtor entry in each of the vtables for foo, baz and quux point at the respective in-charge deleting dtor.
•b1 and b2 are constructed by baz() in-charge, which calls foo(1) in-charge
•q1 and q2 are constructed by quux() in-charge, which falls foo(2) in-charge and baz() not-in-charge with a pointer to the foo object it constructed earlier
•q2 is destructed by ~auto_ptr() in-charge, which calls the virtual dtor ~quux() in-charge deleting, which calls ~baz() not-in-charge, ~foo() in-charge and operator delete.
•q1 is destructed by ~quux() in-charge, which calls ~baz() not-in-charge and ~foo() in-charge
•b2 is destructed by ~auto_ptr() in-charge, which calls the virtual dtor ~baz() in-charge deleting, which calls ~foo() in-charge and operator delete
•b1 is destructed by ~baz() in-charge, which calls ~foo() in-charge
Anyone deriving from quux would use its not-in-charge ctor and dtor and take on the responsibility of creating the foo object.

In principle, the not-in-charge variant is never needed for a class that has no virtual bases; in that case, the in-charge variant is then sometimes called unified, and/or the symbols for both in-charge and not-in-charge are aliased to a single implementation.

 

 

文章来源: http://stackoverflow.com/questions/6613870/gnu-gcc-g-why-does-it-generate-multiple-dtors/6614369#6614369

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值