3


0

私はC用のGUIクラスを構築していて、ポインタをたくさん扱っています。 呼び出し例

mainGui.activeWindow-> activeWidget-> init();

ここでの私の問題は、* activeWidget *ポインタを別の型にキャストしたいということです。 * activeWidget *はGUI_BASE型です。 BASEから派生した私はGUI_BUTTONとGUI_TEXTBOXのような他のクラスがあります。 * activeWidget *ポインタをGUI_BASEからGUI_TEXTBOXにキャストしたいです。 私はそれがこのように見えると思います:

(GUI_TEXTBOX *)(mainGui.activeWindow-> activeWidget) - > function();

コンパイラはポインタがGUI_BASE型であるとまだ考えているため、これは機能しません。 ただし、次のコードは機能します。

GUI_TEXTBOX * textbox_pointer; textbox_pointer =(GUI_TEXTBOX *)mainGui.activeWindow-> activeWidget; textbox_pointer-> function();

私のここでの問題が単なる構文上の問題であることを願っています。 助けてくれてありがとう :)

9 Answer


18


問題はキャストが。よりも優先順位が低いことです。 - >()[]演算子 Cスタイルのキャストを使用するか、括弧を追加する必要があります。

((GUI_TEXTBOX *)mainGui.activeWindow-> activeWidget) - > function(); //余分な括弧dynamic_cast(mainGui.activeWindow-> activeWidget) - > function(); // Cスタイルキャスト


9


あなたはCスタイルのキャストを使ってはいけません。

あなたはCの動的キャストを使う必要があります。 これにより、メソッドを呼び出す前に、オブジェクトが実際にはGUI_TEXTBOXであることをテストできます。

GUI_TEXTBOX * textboxPointer = dynamic_cast(mainGui.activeWindow-> activeWidget); if(textboxPointer){// activeWidgetがテキストボックスではない場合、dynamic_castは// NULLを返す。 textboxPointer-> textBoxMethod(); }

// or

dynamic_cast(* mainGui.activeWindow-> activeWidget).textBoxMethod();

// This will throw bad_cast if the activeWidget is not a GUI_TEXTBOX

Cスタイルのキャストとreinterpret_cast <>()はこの状況で動作することが保証されていないことに注意してください(たいていのコンパイラではそうなるでしょうが[これは実装の単なる側面であり、幸運です])。 activeWidgetに割り当てられたオブジェクトが実際に多重継承を使用している場合、すべての賭けは無効になります。この場合、dynamic_cast <>()を使用しないと、ほとんどのコンパイラで奇妙なエラーが発生します。


4


括弧がもっと必要です。

((GUI_TEXTBOX *)(mainGui.activeWindow-> activeWidget)) - > function();

実際には、これもうまくいくでしょう:

((GUI_TEXTBOX *)mainGui.activeWindow-> activeWidget) - > function();


3


他の人が指摘したように:

((GUI_TEXTBOX*)(mainGui.activeWindow->activeWidget))->function();

その理由は、 ` - >`演算子が型キャストよりも優先順位が高いからです。

'' '' '

私はSteve Ouallineの "Practical C"のルールのために別のプラグインをここに入れます。

_ _ Cには15の優先順位規則があります(&&は||の前に?:が来る前に?:)。 実用的なプログラマーはこれらを2つに減らします。

1)乗算と除算は、加算と減算の前に行われます。

2)他のものすべての周りに括弧を置きます。 _ _

'' '' '

そして最後に、ダウンキャストは危険な場合があります。詳細については、https://stackoverflow.com/questions/331937/what-am-i-doing-wrong-with-this-pointer-cast#332004 [Martin York’s answer]を参照してください。キャストを安全に実行するために `dynamic_cast <>`を使う。


1


それは演算子の順序の問題です(演算子の優先順位)。 うまくいかなかったコードを考えてみてください。

_ (GUI_TEXTBOX *)(mainGui.activeWindow→ activeWidget) - > function(); _

ここで、 ` - >`演算子はあなたのキャストよりも優先されます。 それが他のコードサンプルが機能する理由です。 他のサンプルでは、​​最初に明示的にキャストしてから関数を呼び出します。 より合理的にするために、コードが次のようになるように括弧の別のセットを追加してみてください。

_ ((GUI_TEXTBOX *)(mainGui.activeWindow→ activeWidget)) - > function(); _


1


2つの戦略があります。 1つは「速く失敗する」です。間違った型にキャストした場合は、例外がスローされるので、すぐに間違った型にキャストしたことに気付くでしょう。 もう1つは「高速実行」です。キャストの宛先タイプの確認は行われません。 このキャストは、自分が間違ってはいけないことがわかっている場合、または基底または派生型を持つ多相型がない場合にのみ使用してください。 私はあなたのニーズに応じて以下をお勧めします(あなたがキャストするときはconstを保つことを忘れないでください)

dynamic_cast(*mainGui.activeWindow->activeWidget).function();
Fail fast:間違った型にキャストした場合は `std

bad_cast`をスローします。

static_cast(mainGui.activeWindow->activeWidget)->function();

Run fast:実行時チェックを行いません。 それで速く失敗することはありません。 そうではなく、間違った型にキャストすると、未定義の動作が発生します。 注意してください。


0


((GUI_TEXTBOX *)(mainGui.activeWindow-> activeWidget)) - > function();


0


  • >は(キャスト)よりも優先順位が高いため、メンバーアクセスはキャストの前に行われます。 演算子の優先順位については、こちらを参照してください。http://www.cppreference.com/wiki/operator_precedence

上記のように、括弧がもっと必要です。


0


if(GUI_TEXTBOX * ptr = dynamic_cast(mainGui.activeWindow-> activeWidget)){ptr-> function(); }

その理由は、キャストしようとしているポインタが実際にはGUI_TEXTBOXオブジェクトを指していない可能性があり、テキストボックスメソッドを呼び出す前にそれを確認したいためです。 これにはCの動的キャストが必要です。