2009-03-13 8 views
1

なぜ仮想動作が防止されていますか?メンバー関数へのポインタを格納することによる仮想動作

class MyClass 
    { 
     //........ 
     virtual double GetX(); 
     virtual double GetSomethingElse(); 
     virtual double GetT(); 
     virtual double GetRR(); 
     //........ 

    }; 

    class Processor 
    { 
    private: 
      typedef double (MyClass::*MemFuncGetter)(); 
      static map<std::string, MemFuncGetter> descrToFuncMap; 

    public: 
      static void Initialize(); 
      void Process(Myclass m, string); 

    }; 

    void Processor::Initialize() 
    { 

     descrToFuncMap["X"]=&MyClass::GetX; 
     descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse; 
     descrToFuncMap["RR"]=&MyClass::GetRR; 
     descrToFuncMap["T"]=&MyClass::GetT; 
    }; 

    void Processor::Process(MyClass *ms, const std::string& key) 
    { 
     map<std::string, Getter>::iterator found=descrToFuncMap.find(key); 
     if(found!=descrToFuncMap.end()) 
     { 
      MemFuncGetter memFunc=found->second; 
      double dResult=(ms).*memFunc(); 
      std::cout<<"Command="<<key<<", and result="<<result<<std::end; 
      } 
    } 
+0

継承は次のとおりです。ここで

はチュートリアル/例ですか? –

+0

あなたが見ているものと見たいものであなたの例を上げてください。 –

+0

あなたの行動とあなたが持っているものによってあなたが期待するものを記述してください。 – bayda

答えて

7

ここでこの行:

void Processor::Process(MyClass ms, const std::string& key) 

は、あなたがMyClassののサブクラスに合格した場合でも、slicing何が起きていると呼ばれる

void Processor::Process(MyClass &ms, const std::string& key) 

とそれを交換してみてくださいProcessを呼び出すと、新しいMyClassオブジェクトがMyCLassのコピーコンストラクタを使用してスタック上に作成されます。この新しいオブジェクトは、MyClassの仮想テーブルを持っていることを含め、いつものMyClassです。

参照渡し、またはポインタを使用すると、コピーが作成されず、MyClassへの参照は、実際にはSubClassOfMyClass型のオブジェクトを参照する可能性があります。

編集:

出力
class MyClass 
{ 
public: 
    //........ 
    virtual double GetX() { return 0.0; } 
}; 

class MyClass2 : public MyClass 
{ 
public: 
    //........ 
    virtual double GetX() { return 1.0; } 
}; 

class Processor 
{ 
public: 
    typedef double (MyClass::*MemFuncGetter)(); 
    static void Initialize(); 
    void Process(MyClass *m, const string &); 
private: 
    static map<std::string, MemFuncGetter> descrToFuncMap; 
}; 

void Processor::Initialize() 
{ 
    descrToFuncMap["X"]=&MyClass::GetX; 
} 

void Processor::Process(MyClass *ms, const std::string& key) 
{ 
    map<std::string, MemFuncGetter>::iterator found=descrToFuncMap.find(key); 
    if(found!=descrToFuncMap.end()) 
    { 
     MemFuncGetter memFunc=found->second; 
     double dResult=(ms->*memFunc)(); 
     std::cout<<"Command="<<key<<", and result="<<dResult<<std::endl; 
     } 
} 

map<std::string, Processor::MemFuncGetter> Processor::descrToFuncMap; 

int main() 
{ 
    Processor::Initialize(); 
    Processor p; 

    MyClass2 mc2; 
    p.Process(&mc2, "X"); 
} 

さて、問題は、あなたがこれを取得する場合、それをコンパイルするには、すべてがうまく動作しますが、多くのコンパイルエラーのいずれかであります

コマンド= X、結果= 1

+0

それはポインタとして渡されます - スライシングなし –

1

ワウ私はサンプルピースを見たことがありません実際の問題になる前に、他の多くの構文エラーがあります。

投稿する際には、助けたい人が編集可能である必要があります。
1つのバグを除いて、他の人にあなたを手伝ってもらいたいと思います。

あなたが達成しようとしていることはわかりませんが、仮想機能ではありません。だからあなたはあなたの質問に名前を変えるべきです。

私はあなたの主な問題は、この行であると推測:あなたはジョシュのアドバイスを受け入れた場合、構文は次のようになりますによって

MemFuncGetter memFunc=found->second; 
double dResult=(ms).*memFunc(); 

MemFuncGetter memFunc=found->second; 
double dResult=(ms.*memFunc)(); // MyClass& ms 

-- or 

double dResult=(ms->*memFunc)(); // MyClass* ms 
1

boost :: bindとboost :: functionを使用したことはありますか?ポインタをフリー/メンバ関数にバインドすることができます。また、遅延呼び出しのために特定のパラメータをバインドすることもできます。 http://www.codeproject.com/KB/library/BoostBindFunction.aspx

+0

私はしましたが、私が働く会社はそうではありません –

関連する問題