const-refとd'torのvirtual dispatch
http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry
http://d.hatena.ne.jp/faith_and_brave/20080107/1199696826
Q3 : 参照がスコープから抜けるとき、どのデストラクタが呼ばれるでしょうか?
A3 : 一時オブジェクトのために呼ばれるのと同じデストラクタが呼ばれます。
当然の結果:Derived一時オブジェクトをconst Base&に持つことができます。
そしてそれは仮想ディスパッチなしのデストラクタが呼び出されます。
これは素晴らしいです。
…?
えーと、こういうこと?
#include <iostream> #include <string> using namespace std; //#define virtual /* */ struct base { string name; base(const string& n) : name(n) { cout << "base::base " << name << endl; } virtual ~base() { cout << "base::~base " << name << endl; } }; struct derived : public base { derived(const string& n) : base(n) { cout << "derived::derived " << name << endl; } virtual ~derived() { cout << "derived::~derived " << name << endl; } }; derived gen() { return derived("b"); } void foo() { const base& b = gen(); } int main() { derived a("a"); foo(); base* c = new derived("c"); delete c; }
ちゃんとvirtualをつけるとa, b, cのいずれもderivedとbaseの両方のデストラクタが呼ばれるけれど、virtualをつけない場合、cはbaseのデストラクタだけを呼ぶ(なぜならdeleteの時点ではcの型は静的にbase*に決まるから)。一方でbは、virtualの有無に関係なくderivedのデストラクタを呼ぶ。なぜならbに束縛された時点で、束縛した対象がderivedであることが分かっているから。
…へえ。
あとQ1の
[Jan 2 update: Note this only applies to stack-based references. It doesn't work for references that are members of objects.]
も重要…っと。