3

スライスの危険性はありますか

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

どこ

class Block : Object {/*Filler*/}

obj1とはオブジェクトobj2であることが保証されていBlockますか?

私は使いたくなる:

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

しかし、SO の object-slicing タグの簡単な説明を読むと、前者を使用したくなります。しかし、厄介なサイレントスライスは本当に望んでいません。

4

2 に答える 2

9

参照とポインターはどちらも多態的です。

あなたは好むかもしれません

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

参照から始まるダウンキャストの場合は、 と同等*static_cast<const Block*>(&obj1)です。

于 2012-02-14T19:30:09.243 に答える
1

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

とはいえ、参照やポインターをダウンキャストするときは、スライスについて心配する必要はありません。

ポリモーフィック オブジェクト (つまり、仮想メソッドを持つオブジェクト) の場合、動的キャストを使用できます。これにより、コンパイル時 + 実行時チェックが可能になります (ポインターを間違った型にダウンキャストすると null が返され、間違った型への参照をダウンキャストすると bad_cast 例外がスローされます)。タイプ):

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

非ポリモーフィック オブジェクトの場合は、 を使用できますstatic_cast

于 2012-02-14T19:31:29.327 に答える