0

サブクラスの基本クラス関数をオーバーライドしますShowPropertiesが、それでも基本クラス関数が呼び出されます。どうしてこれなの?

クラス階層:

class CDiagramEntity : public CObject
{
public:
  virtual void ShowProperties( CWnd* parent, BOOL show = TRUE );
}

class CNetworkSymbol : public CDiagramEntity
{
  /*NO 'ShowProperties' Function*/
}

class CDeviceEntity : public CNetworkSymbol
{
  /*NO 'ShowProperties' Function*/
}

class CSwitch : public CDeviceEntity
{
public:
  virtual void ShowProperties( CWnd* parent, BOOL show = TRUE );
}

使用する:

/*Use Here*/
{
  CDiagramEntity* obj = GetSelectedObject();
  if( obj )
  {
    CSwitch* sw = (CSwitch*)obj;
     sw->ShowProperties( this );    
     /*calls CDiagramEntity's function, not CSwitch's function*/
  }
}

PS:

  1. @iammilindが示唆しているように、CDiagramEntityから仮想を削除してキャストを使用すると、CSwitchの関数が呼び出され、表示されるプロパティ(プロパティはCSwitchの作成時に表示されるものにのみ変更できます)から、 CSwitch。
  2. @ user1610015のコメントとして、私が使用する場合

    CSwitch* sw = dynamic_cast<CSwitch*>(obj);
    

    を返しますNULL

  3. @Andrian Shamが言うように、私は問題の理由を理解しました:

    GetSelectedObject()--->finally calls--->
    {
      CDiagramEntity* result = NULL;
      if ( index < m_objs.GetSize() && index >= 0 )
        result = static_cast< CDiagramEntity* >( m_objs.GetAt( index ) );
      /*m_objs is defined as: CObArray m_objs;*/
      return result;
    }
    

m_objs:

CObArray m_objs;

そして、オブジェクトは次のように保存されます。

...( CDiagramEntity* obj )
{
  obj->SetParent( this );
  m_objs.Add( obj );
  SetModified( TRUE );
}

しかし、誰かがこれをより詳細に説明できますか?

4

3 に答える 3

2

デバッグの方法がわかりません。あなたはCSwitchのメンバー変数を見ることができると言いました。CSwitch* sw = (CSwitch*)obj;あなたがそのようなvarを調べて見ることを意味するならsw、あなたは実際に間違っているのです。swデバッガーは、CSwitchであるため、ポイントされたメモリの一部を単に「解釈」しています。それが本当にCSwitchであるという意味ではありません。

私は事件を考えることしかできません。オブジェクトインスタンスを任意のSTLコンテナーに配置し、それを取り出して選択アイテムとして配置しましたか?

(MFCを完全に忘れました。これは単なる例です)

vector<CDiagramEntity> entities;  // note it is of type CDiagramEntity, not CDiagramEntity*

CSwitch aCSwitch;
entities.push_back(aCSwitch);

// later
SetItem("SomeValue", entities[i]);

エンティティ[i]はCSwitchのインスタンスを返す必要があると思うかもしれませんが、そうではありません。

(これは、選択したアイテムがCSwitchであることがかなり確実である場合に推測できる最良のものです)

于 2012-11-21T04:20:01.390 に答える
1

ShowProperties()virtual関数だ からです。

メカニズムが作動すると、実行時virtualに関数バインディングが発生します。がのオブジェクトを返す 場合、ポインタの型に関係なく呼び出されます(ここ)。
ShowProperties()class CDiagramEntityCDiagramEntity::ShowProperties()static typesw

実験のために、virtualキーワードを削除してコードを実行します。期待される動作が得られます。ただし、未定義の動作の可能性に注意してください。

于 2012-11-21T03:41:42.010 に答える
1

CDiagramEntityオブジェクトをCSwitchオブジェクトにキャストした場合でも、仮想ディスパッチを介して呼び出しが行われるためです。したがって、GetSelectedObjectによって返されるオブジェクトが実際にはCSwitchでない場合、CDiagramEntityのShowPropertiesが呼び出されます。

オブジェクトをCSwitchにキャストするのはなぜですか?デザインの観点からは意味がありません。ポリモーフィックオブジェクトがありますが、それを特殊な派生物の1つとして扱いたいと考えています。

于 2012-11-21T03:43:18.970 に答える