2011-12-15 4 views
3

私は、クラスYがYとZ(インタフェース)から派生しています。このクラスのオブジェクトは、インタフェースZのみにアクセスできるvoid *としてライブラリに渡されます。[Z *として渡されない理由は、void *を受け付ける中間コンポーネントです]gccが多重継承のハックをハックする

gccサンクスのvtableはX、Yは同じアドレスを指しますが、ZはX + 8を指します。

したがって、私はオブジェクトをZに到達するために(Z *)(obj + 8)として型キャストする必要があります。この安全な、代替がありますか?私はRTTIを使うことができません。

+1

static_cast (reinterpret_cast (obj))ここでobjはvoid * –

+2

あなたのデザインに何か問題があると思います。もしend-of-chain関数が常に*にキャストされるvoid *を取得するとすれば、void *の代わりにZ *をとるように最初のチェーン内関数を変更するだけです(そして内部的にそれを渡しますさらにvoid *として)。あなたはきれいなインターフェイスを取得し、コンパイラは、すべての汚い作業を行うこのように。 – elmo

答えて

2

いいえ、キャスト(Z*)(obj + 8)は安全ではありません。

はバックZ*void*をキャストし、その後、void*にキャストする前Z*にオブジェクトをキャストします。それは安全です。

3

この場合、static_castで送信するタイプに明示的にキャストしてください。それは、両方のタイプが変換中であることを知っている限り、詳細を処理します。受信コードで次に

X *theX = ...; 
void *ptr = static_cast<Z*>(theX) 

:ある

void *ptr = ...; 
Z *theZ = static_cast<Z*>(ptr); 

そして、あなたはを知ってかどうかは、実際にXです:

X *theX = static_cast<X*>(theZ); 

ボトムラインあなたがポインタをにキャストするたびにとそれ以前のものと同じタイプに変換する必要があります。

したがって、これは定義されていません:

X *theX = ...; 
void *ptr = static_cast<void*>(theX); 
Z *theZ = static_cast<Z*>(ptr); //Undefined behavior!!! 

イベントZXのサブクラスであり、2つの間の直接static_castが働いているだろうけれども。