2016-04-30 62 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,它是的virtual函數。 閱讀關於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

對不起,這就是我的意思。 Ment覆蓋,父函數的不同實現,相同的簽名。但問題依然存在。爲什麼新方法不起作用? – parsecer

+1

@parsecer我已經更新了我的答案。 – fghj

+0

感謝您的回覆!但它仍然不完全清楚。是不是我的情況就像'Boo'中有一個'f2()'函數一樣,它和'f()'是'cout <<「foo:f \ n'完全相同。 'Boo'對象調用該函數並沒有什麼錯...... – parsecer