1. 程式人生 > >C++ 中提供的override 關鍵字

C++ 中提供的override 關鍵字

C++ 語言標準這些年進化的很快,許多新引入的特性我都沒有用過。說實話自己也比較懶,總是覺得自己對C++ 的掌握程度已經足夠應付日常的各種專案了,所以沒有學習新特性的動力。而且一直覺得新引入的特性多數都屬於那種“語法糖”,能夠發揮的作用不大,其實是可有可無的。

不過最近編寫一個小程式時程式碼裡有個小bug,困擾了我好幾天。最後在幾個熱心網友的幫助下才解決了。這個小bug讓我認識到C++11 中提供的override 關鍵字非常有用,下面就簡單的說說我程式碼中的那個小bug

我的那個程式碼是個利用Qt 寫的GUI程式,程式中需要響應滑鼠的mouseMoveEvent 事件。但是結果怎麼也接收不到這個事件。下面是我的程式的一個簡化版本。

//MyWidget.h
#ifndef MW_H
#define MW_H
#include <QWidget>
class MyWidget : public QWidget
{
     Q_OBJECT
public:
     MyWidget(QWidget *parent = 0);
     ~MyWidget();
  
protected:
	void mousePressEvent( QMouseEvent * event ) ;
	void mouseReleaseEvent( QMouseEvent * event ) ;
	void mouseMoveEvent( QMoveEvent * event ) ;
};
  
#endif

//MyWidget.cpp
#include "MyWidget.h"
#include <QDebug>
MyWidget::MyWidget(QWidget *parent):QWidget(parent)
{
}
MyWidget::~MyWidget()
{

}
void MyWidget::mousePressEvent( QMouseEvent * event ) 
{
	Q_UNUSED(event);
    qDebug() << "mousePressEvent";
}
void MyWidget::mouseReleaseEvent( QMouseEvent * event )
{
	Q_UNUSED(event);
    qDebug() << "mouseReleaseEvent";
}
void MyWidget::mouseMoveEvent( QMoveEvent * event )
{
	Q_UNUSED(event);
    qDebug() << "mouseMoveEvent";
}


//main.cpp
#include <QApplication>
#include "MyWidget.h"
int main(int argc, char **argv)
{
     QApplication app(argc, argv);
MyWidget win;
     win.show();
     return app.exec();
} 

這個程式執行的結果如下:

我甚至一度認為我用的這個Qt版本出了bug。後來換了好幾個Qt版本,甚至於到linux下還試了試,結果都是一樣的。折騰了好幾天,最後發現是我把函式原型寫錯了。本應是:

void mouseMoveEvent( QMouseEvent * event );

我錯寫為:

void mouseMoveEvent( QMoveEvent * event );

而且剛巧 Qt中有 QMoveEvent 這個類,所以這個程式碼編譯時什麼錯誤提示都沒有。之所以這裡會寫錯,是因為Qt中有另外一個事件,原型是:

void moveEvent( QMoveEvent * event );

最開始我錯將這個事件當成滑鼠移動事件了,後來發現還有個mouseMoveEvent就隨手將函式名改過來了,但是沒注意後面的引數型別是不同的,結果就悲劇了。

如果使用了 override 關鍵字,這種錯誤是很容易避免的。

//MyWidget.h
#ifndef MW_H
#define MW_H
#include <QWidget>
class MyWidget : public QWidget
{
     Q_OBJECT
public:
     MyWidget(QWidget *parent = 0);
     ~MyWidget();
  
protected:
	void mousePressEvent( QMouseEvent * event ) override;
	void mouseReleaseEvent( QMouseEvent * event ) override;
	void mouseMoveEvent( QMoveEvent * event ) override;
};
  
#endif

再次編譯,就會提示

‘void MyWidget::mouseMoveEvent( QMoveEvent * event )’marked override, but does not override

不過override 關鍵字需要編譯器支援 C++11。如果使用的是 gcc 編譯器,需要加入命令列引數 -std=c++11

如果是用qt的話,要在pro檔案中增加如下內容:

QMAKE_CXXFLAGS += "-std=c++11"

相關推薦

C++ 提供override 關鍵字

C++ 語言標準這些年進化的很快,許多新引入的特性我都沒有用過。說實話自己也比較懶,總是覺得自己對C++ 的掌握程度已經足夠應付日常的各種專案了,所以沒有學習新特性的動力。而且一直覺得新引入的特性多數都屬於那種“語法糖”,能夠發揮的作用不大,其實是可有可無的。 不過最近編寫

C++的static關鍵字的總結(轉)

blank protected .com 如果 發現 內部實現 屬於 out 服務  C++的static有兩種用法:面向過程程序設計中的static和面向對象程序設計中的static。前者應用於普通變量和函數,不涉及類;後者主要說明static在類中的作用。 1.面向過程

C++ 的explicit關鍵字

操作符 希望 疑惑 ive 有一個 編譯器 自動類型轉換 幫我 con explicit關鍵字在c++中是為了防止隱式轉換 (1) explicit 此關鍵字只能對用戶自己定義的對象起作用,不對默認構造函數起作用此關鍵字只能夠修飾構造函數。而且構造函數的參數只能有一個。。

C++的static關鍵字

不能 get () turn out nbsp 所有 說明 靜態 類中的成員可分為普通成員和靜態成員,函數可分為普通函數和靜態函數。普通成員只能是每個對象獨自擁有,而靜態成員則是類的所有對象所共有的。靜態成員函數中,只能調用靜態成員變量,不能調用普通成員變量。 例如:

C#的volatile關鍵字

ola 關鍵字 current ember oop doc test word sharp volatile 關鍵字指示一個字段可以由多個同時執行的線程修改。 聲明為 volatile 的字段不受編譯器優化(假定由單個線程訪問)的限制。 這樣可以確保該字段在任何時間呈現的都

【轉】c++的static關鍵字總結

個人總結: static會隱藏全域性變數和全域性函式可見範圍,使其盡在定義檔案中可見; static會改變區域性變數生存週期,在程式中一直存在,而不僅僅在區域性變數定義的函式中; static會改變類的成員變數的生存週期,在程式中一直存在; static會修改函式的使用方

C++的virtual關鍵字

虛擬函式與執行多型 多型: 多型按字面的意思就是多種形態。當類之間存在層次結構,並且類之間是通過繼承關聯時,就會用到多型。C++ 多型意味著呼叫成員函式時,會根據呼叫函式的物件的型別來執行不同的函式。 先看最簡單的情況,也就是最普通形式的繼承,且父類和子類的方法都是一般成員方法:

C++的explicit關鍵字

在C++中,explicit關鍵字用來修飾類的建構函式,被修飾的建構函式的類,不能發生相應的隱式型別轉換,只能以顯示的方式進行型別轉換。 例如:不加explicit的隱式轉換: class Circle { public: Circle(

C++的explicit關鍵字介紹

C++中的關鍵字explicit主要是用來修飾類的建構函式,被修飾的建構函式的類,不能發生相應的隱式型別轉換,只能以顯示的方式進行型別轉換。類建構函式預設情況下宣告為隱式的即implicit。  隱式轉換即是可以由單個實參來呼叫的建構函式定義了一個從形參型別到該類型別的隱式轉換。編譯器

C++的mutable關鍵字【轉】

mutalbe的中文意思是“可變的,易變的”,跟constant(既C++中的const)是反義詞。     在C++中,mutable也是為了突破const的限制而設定的。被mutable修飾的變數,將永遠處於可變的狀態,即使在一個const函式中。     我們知道,

C# 的var關鍵字

var 是3.5新出的一個定義變數的型別 其實也就是弱化型別的定義 VAR可代替任何型別 編譯器會根據上下文來判斷你到底是想用什麼型別的 至於什麼情況下用到VAR 我想就是你無法確定自己將用的是什麼型別 就可以使用VAR 類似 OBJECT 但是效率比OBJECT高點。

C#的global關鍵字

global關鍵字,就是字面的意思,全域性。 其實有些時候會犯一些錯誤,就是類名取了一個跟系統類名雷同的情況,其實這是設計上的失誤,但是會出現一個情況就是沒改了,那麼global關鍵字就起到了作用。 如下程式碼: using System; using System.C

C#的this關鍵字

C# this關鍵字的四種用法 - 天碼行空 - 部落格園 https://www.cnblogs.com/jh007/p/6120654.html C#中this關鍵字詳解 - lin37985的專欄 - CSDN部落格 https://blog.csdn.net/lin

C#使用typeof關鍵字和GetType()獲取類的內部結構(反射機制)

一、問題描述 java有反射機制,C#也有反射機制,在C#中typeof關鍵字用於獲取型別的System.Type物件,該物件的GetMethods()方法可以得到型別中定義的方法物件的計集合,呼叫方法集合中每個方法物件的GetParameters()可以得到每個方法的引數

[C#-1] C#event的關鍵字存在的意義

C#中事件是基於委託。 不使用event關鍵字定義委託例項物件: //定義一委託型別 publicdelegatevoid MyButtonEventHandler(string msg);   //定義MyButton類,模擬按鈕物件 publicclass

淺析C語言auto關鍵字C++ 的auto關鍵字

      最近在讀《C++ Prime》,不禁想感嘆一句:C++真是一種美麗的語言!!!!!!!      C++提供了相比於 C語言更加豐富的庫函式,功也更加強大。舉個例子吧。      題目:編寫一段程式,讀入一段包含標點符號的字串,將標點符號去除後輸出字串剩餘的部分。

C#的partial關鍵字的作用

  使用partial修飾的類可以在同一個檔案下面寫相同的類名,簡單的理解就是可以動態的新增欄位:   public  partial class ManagerMenu     {         public int id { get; set; }         p

C++的typename關鍵字

在C++中typename除了用於在定義模板函式和模板類中來替代關鍵字class,例如template<class T>換成template<typename T>意外,typename還可以用來做型別的定義。 注意:下面的程式碼是有問題的 temp

C++的inline關鍵字

1. 引入inline關鍵字的原因 在c/c++中,為了解決一些頻繁呼叫的小函式大量消耗棧空間(棧記憶體)的問題,特別的引入了inline修飾符,表示為行內函數。 棧空間就是指放置程式的區域性資料(也就是函式內資料)的記憶體空間。 在系統下,棧空間

C++ 關於override和final使用

C++使用虛方法實現多型,讓基類引用或者指標能夠指向子類的對應的方法,從而實現多型。 1、但是也會出現一些問題,例如基類中聲明瞭一個虛方法,但是在派生類中提供了不同版本的方法,就會隱藏掉子類中的方法。 #pragma once #include <