1

同様の名前のサブ/スーパークラス関数を呼び出す仮想関数について、大量のスタック オーバーフローの質問と回答が表示されますが、次のようになります。

CCLog("Yay"); //ensure it's called
CCScene * tScene = TitleDescription::scene(); //grab the scene

TitleDescription * t = reinterpret_cast<TitleDescription *>(tScene); //Unsure why this even works when I think about it, a scene is returned but the below call:

t->loadWithDataFrom("Information.xml", "story"); //calls setScaleX on CCObject instead.

CCDirector::sharedDirector()->replaceScene(tScene ); //runs with an empty scene on one condition

シーンが loadWithData で読み込まれる条件は、関数を void name(types) にすることです。私は cocos2d-x のパターンに従って virtual を使用しました。その場合は代わりに setScaleX を呼び出し、デバッガーを使用してステップインしました。

2 つの質問があります。

1) scene() 関数がシーン (TitleDescription タイプの子ノードを持つ) を返す場合、この呼び出しはどのように機能しますか?

2) めちゃくちゃになったとき、vTable はガベージの場所を指しているだけですか? それはたまたま同じ関数ですか?

注: cocos2d (および X) では、シーンはレイヤーのサブクラスであり、CCObject をサブクラス化します。CCObject には呼び出される関数が含まれていますが、名前とパラメーターが大きく異なり、名前とパラメーターが完全に異なる関数が呼び出される理由がわかりません。

私は、これに関する参考文献や優れたドキュメントを受け入れています。私のキャスト (すべてを強制的にバイパスするためだけに再解釈するように設定) が、署名を void ではなく bool に変更し、ビルドをクリーンアップする場合を含め、実行ごとに仮想関数が同じ関数を指している可能性があるのではないかと疑っています。 .

注:XCodeは私がいる環境です。LLVMもまだ使用しているとは思いません。私はそれを微調整して、何が起こるか見てみます。

他のみんなと同じように、抽象クラスの使用と強制オーバーライドについては知っていても、vFunctions を完全に理解しているとは思いません。(その関数を持つ最初のクラスであるため、現時点でなぜ仮想化する必要があるのか​​ わかりませんが、私がやっていることのためにサブクラスで関数を拡張する予定です)。

ありがとう、スティーブ・J

4

1 に答える 1

3

reinterpret_cast正しくダウンキャストされません。ベースサブオブジェクトが完全なオブジェクトの先頭にない場合があることに注意してください。

アップキャスト、ダウンキャスト、およびstatic_castクロスキャストには暗黙の変換を使用し ます。必要に応じて適切なオフセットが含まれ、同じアドレスを返すだけではありません。dynamic_castdynamic_castreinterpret_cast

そして、これらのどれも、親とメンバー(非ベース)サブオブジェクトの間にあなたを連れて行くことはありません。

キャストを完全に回避するのが最善です。

于 2012-04-28T23:11:41.717 に答える