2016-04-30 5 views
0

私はエスケープキープレスを扱う次のクラスを持っています。 keypresseventとそのオーバーロード

  class KeyPress : public QWidget 
     { 
      Q_OBJECT 
      public: 
      KeyPress(QWidget * parent=0); 

      protected: 
      void keyPressEvent(QKeyEvent * event); 

     }; 

と.cppファイル:

  void KeyPress::keyPressEvent(QKeyEvent *event) 
      { 

       if (event->key() == Qt::Key_Escape) { 
        qApp->quit(); 
          } 
      } 

それは正常に動作しますが、私は、keyPressed(QKeyEvent * event)を言うために、メソッドの名前を変更した場合、それは動作しません。文書によるkeyPressEvent(QKeyEvent * event)の方法は、QWidgetの保護された方法である。 最初のコードはそのメソッドをオーバーロードしていませんか?そして、過負荷が働く。しかし、別の名前で同じ実装の全く新しいバージョンのメソッドが動作しないのはなぜですか?

答えて

2

overloadではなく、overridevirtualの機能です。 c++virtualについて読む例えば

:なぜならptr->f()コンパイラのための

#include <iostream> 

using std::cout; 
struct Foo { /*virtual*/void f() { cout << "foo:f\n"; } }; 
struct Boo : public Foo { void f() { cout << "boo:f\n"; } }; 

int main() 
{ 
    Boo boo; 
    Foo *ptr = &boo; 
    ptr->f(); 
} 

なコード印刷foo:fは、このような何かを生成:

address_of_function = &Foo::f; 
call address_of_function 

をしかし、あなたは私のサンプルコードではvirtualコメントを解除boo:f、 を印刷するかどうかvirtualのため、このようなコードに似たコンパイラが生成されます。

address_of_function = ptr->virtual_table_of_Foo_class[offset_of_f] 
call address_of_function 

ptrポイントは、クラスの仮想テーブルをブーイングする、とaddress_of_functionが等しい&Boo::fなり、この方法virtualの機能が動作します。

だからあなたの場合はFoo == QWidget、それはQtのこの内部のようなコードがあります。

this->keyPressEvent(); 

、仮想テーブルにkeyPressEventのアドレスを取得し、それを呼び出します。明らかにKeyPress::someOtherFunctionを実装すると、既にコンパイルされたコードQtが呼び出されないため、呼び出されません。

+0

申し訳ありませんが、それは私の言いたいことです。私は、親の機能の異なる実装、同じ署名を上書きします。しかし、疑問はまだ残っています。なぜ新しい方法がうまくいかないのですか? – parsecer

+1

@parsecer私は自分の答えを更新しました。 – fghj

+0

返信いただきありがとうございます!しかし、それはまだ完全にはっきりしていません。私の状況は、 'foo(foo:f \ n')と同じことをした' Boo'に 'f2()'関数があったのと同じですか?その関数を呼び出す 'Boo'オブジェクトには何も間違ってはいけません... – parsecer

関連する問題