override和final標識符

override和final標識符

overridefinal是C++引入的新的標識符。注意是標識符不是關鍵字。

標識符和關鍵字的區別

關鍵字(KEYWORD):也稱保留字。它們爲語言所用,不可用於重定義或重載。

標識符(IDENTIFIERS):一個標識符是一個由數字,下劃線,小寫和大寫拉丁字母,和大多數 Unicode 字符組成的任意長度的序列。在聲明中,可以用標識符來命名對象、引用、函數、枚舉項、類型、類成員、命名空間、模板、模板特化、形參包、goto 標號,以及其他實體。

override和final標識符: 擁有特殊含義的標識符,可用作對象或函數的名字,但在某些語境擁有特殊含義。

也就是說,override和final也是標識符,也可以作爲對象名,或函數名。只是在特殊的語境中有特殊的含義,和作爲對象名和函數名是不衝突的。但關鍵字不可以這樣。

例子:

#include <iostream>
class A {
public:
    virtual void show() {
        std::cout << "A::show(), override = " << override << std::endl;
    }
private:
    int override = 1;
};

class B : public A {
public:
    virtual void show() override {
        std::cout << "B::show(), override = " << override << std::endl;
    }
private:
    int override = 2;
};

int main() {
    A* ptr1 = new A();
    A* ptr2 = new B();
    ptr1->show();
    ptr2->show();
}

輸出

A::show(), override = 1
B::show(), override = 2

作爲函數名也是可以的,但不能同時命名override爲對象名和函數名,就不舉例說明了。

因爲是C++11才引入的,編譯時要指定C++11,否則編譯有告警提示

warning: override controls (override/final) only available with -std=c++11 or -std=gnu++11 [enabled by default]

override標識符

爲什麼要引入override標識符? C++11以前沒有時,是什麼樣?

還是剛纔的例子:

#include <iostream>
class A {
public:
    virtual void show() {
        std::cout << "A::show(), override = " << override << std::endl;
    }
private:
    int override = 1;
};

class B : public A {
public:
    virtual void show(int a) {    //變化行
        std::cout << "B::show(), override = " << override << std::endl;
    }
private:
    int override = 2;
};

int main() {
    A* ptr1 = new A();
    A* ptr2 = new B();
    ptr1->show();
    ptr2->show();
}

輸出

A::show(), override = 1
A::show(), override = 1

因爲Class B的本意是重寫Class A的show方法。 由於參數不一致,導致是新增了一個虛函數。由於沒有重寫基類方法,無法多態調用到派生類的方法。

重寫函數必須有相同的類型,名稱和參數列表。需要人爲去保證,往往容易出現錯誤,導致和預期不一致。

當需要重寫基類方法時,使用override關鍵字,這樣可以將重寫的檢查工作交給編譯器會去做。

例子中增加關鍵字override:

...
	virtual void show(int a) override {
...

編譯將報錯:

error: ‘virtual void B::show(int)’ marked override, but does not override

所有override標識符的作用是: 將重寫的檢查交給編譯器,減少人爲出錯的可能。

在重寫基類方法時,加上override標識符是正確的選擇。

final標識符

final 是在成員函數聲明或類頭部中使用時有特殊含義的標識符。其他語境中它未被保留,而且可用於命名對象或函數。

final可以用於

  • 類聲明: 指定某個類不能被子類繼承。
  • 函數聲明: 指定某個虛函數不能在子類中被覆蓋。

類聲明

class A final {
public:
    virtual void show() {
        std::cout << "A::show(), override = " << override << std::endl;
    }
private:
    int override = 1;
};

如果Class B繼承Class A,編譯將報錯

error: cannot derive from ‘final’ base ‘A’ in derived type ‘B’

函數聲明

    virtual void show() final {
        std::cout << "A::show(), override = " << override << std::endl;
    }

Class B重寫show方法時,也會報錯。

注意:

  1. final不能用於非虛方法。除非這個非虛方法是重寫基類的方法。
  2. 派生類重寫基類的虛方法也可以指定爲final,表示這個方法不能再其被派生類重寫。

參考:

https://zh.cppreference.com/w/cpp/keyword

https://www.bogotobogo.com/cplusplus/C11/C11_override_final.php

https://zh.cppreference.com/w/cpp/language/override

https://zh.cppreference.com/w/cpp/language/fin

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章