2012-02-14 6 views
2

オブジェクト(ポインタではない)を既知の派生型にダウンキャストしても安全ですか?

class Block : Object {/*Filler*/} 

obj1obj2Blockオブジェクトであることを保証されてい

result Compare(const Osp::Base::Object &obj1, const Osp::Base::Object &obj2, int &cmp) const { 
    cmp = ((const Block)obj1).NumSuperBlocks() - ((const Block)obj2).NumSuperBlocks(); 
} 

をスライスする危険性があるだろうか?

私が使用することを誘惑しています:

cmp = ((const Block*)&obj1)->NumSuperBlocks() - ((const Block*)&obj2)->NumSuperBlocks(); 

のが、読んでSOの元を使用するように私が誘惑していたオブジェクト・スライシングタグの簡単な説明です。しかし、私は本当に厄介な静かなスライスを望んでいません。

答えて

7

参照およびポインタは両方とも多型です。

あなたが参照して始まるダウンキャストのため

static_cast<const Block&>(obj1).NumSuperBlocks() 

を好むこと、それは*static_cast<const Block*>(&obj1)に相当します。

+1

'const block 'は関数の引数が' const'です – Lol4t0

+0

@BenVoigt:ポインタとオブジェクトはここでスライスしたのと同じような違いはありませんか? TBH、前者は*がなく、より読みやすく自然な感じです。 – John

+0

@John:ここではポインタと参照の間に違いはありません。私は元のコードが嫌いです。それはスライスすることがあります。また、アクセス可能なコピーコンストラクタを必要とし、コピーで動作します。ここで参照またはポインタを使用します。 –

1

まず、ダウンキャスト用のCスタイルキャスト(またはキャストキャスト)は使用しないでください。すべてのコンパイラチェックを回避するので、非常に危険です。

つまり、リファレンスやポインタをダウンキャストしているときにスライスすることについて心配する必要はありません。

多相オブジェクト(つまり仮想メソッドを持つオブジェクト)では、コンパイル時に+ランタイムチェックを行う動的キャストを使用できます(ポインタを間違った型にダウンキャストするとnullを返します)。間違ったタイプを参照):あなたがstatic_castを使用することができます非多型オブジェクトの場合

Block & block = dynamic_cast<Block&>(obj); 

+1

Cスタイルのキャストは、型が関連しているとき(ここにあるように) 'static_cast'のように振る舞います。そうでなければ' reinterpret_cast'が動作します。したがって、コンパイラはオフセットを処理します。また 'dynamic_cast'は' Object'が 'virtual'メンバ関数を持っている場合にのみ有効です。 –

+0

'dynamic_cast'を使用する場合は、必ず' NULL'の結果を確認してください。 –

+0

@BenVoigt情報をありがとう。私は私のポストを更新します。 – StackedCrooked

関連する問題