3
class Method {
  public:    
  virtual void Rum();
};
class Euler : public Method {
  virtual void Rum() {
    printf("ahoj\n");
  }    
};
class Kutta : public Method {
  virtual void Rum() {
    printf("ahoj2\n");
  }    
};
class Simulator {
  public:
  Method *pointer;
  Simulator();
  void setmethod(Method m) { pointer = &m; }
};

int main() {
  Simulator s;
  s.setmethod(new Kutta());
  s.pointer->Rum();
  s.setmethod(new Euler());
  s.pointer->Rum();
}

この例が十分に理解できることを願っています。継承の原則を適用しようとしましたが、次のエラーが発生しました: (OOP の内容が頭の中で少し混乱しているようです)

prog.cpp: In function ‘int main()’:
prog.cpp:26: error: no matching function for call to ‘Simulator::setmethod(Kutta*)’
prog.cpp:21: note: candidates are: void Simulator::setmethod(Method)
prog.cpp:28: error: no matching function for call to ‘Simulator::setmethod(Euler*)’
prog.cpp:21: note: candidates are: void Simulator::setmethod(Method)

では、親の代わりに子を渡す正しい方法は何ですか? ありがとう!

4

2 に答える 2

5

あなたの署名がvoid setmethod(Method m)正しくありません。void setmethod(Method* m)あなたの呼び出しに一致する必要があります。

setmethod補足として、ポリモーフィズムが機能するには、メソッドに参照またはポインターが必要です。つまり、引数を値で渡して、ポリモーフィズムが機能することを期待することはできません。

于 2012-12-01T21:30:36.183 に答える
3

このコードは動作します:

#include <stdio.h>                                                                                                                                                                                                   

class Method {
  public:    
  virtual void Rum() = 0;
};
class Euler : public Method {
  virtual void Rum() {
    printf("ahoj\n");
  }    
};
class Kutta : public Method {
  virtual void Rum() {
    printf("ahoj2\n");
  }    
  virtual void Rum2() {
    printf("ahoj2blah\n");
  }    
};
class Simulator {
  public:
  Method *pointer;
//  Simulator(); // this was only declaration...
  void setmethod(Method* m) { pointer = m; }
};

int main() {
  Simulator s;
  s.setmethod(new Euler());
  s.pointer->Rum();
  s.setmethod(new Kutta());
  s.pointer->Rum();
//  s.pointer->Rum2(); //you can use only functions from Method
}

まず、メソッドでRum関数を定義する必要があります。 また、が正しくない
理由は 2 つあります。void setmethod(Method m)

  1. new は常にオブジェクトへのポインタを返します
  2. そして最も重要なもの:
    コンパイラは Method タイプのオブジェクトを期待していたため、引数に sizeof(Method) バイトを割り当てました。
    残念ながら、継承されたオブジェクトには追加の変数があることが非常に多いため、そのサイズは親のサイズよりも大きくなります。関数が継承された型を持つオブジェクトを受け入れることができないのはそのためです。
    良い解決策は、常に 8 バイトの関数へのポインターを渡すことです。残念ながら、もう一方を派生させたクラスで定義されたメソッドと変数しか使用できませんが、呼び出したい関数が仮想の場合、オーバーライドされた関数が呼び出されます。
于 2012-12-01T22:49:56.713 に答える