1. 程式人生 > >[C++]成員函式的過載(overload)、覆蓋(override)和隱藏(hide)

[C++]成員函式的過載(overload)、覆蓋(override)和隱藏(hide)

C++成員函式的過載、覆蓋和隱藏

1. 過載與覆蓋

成員函式被過載的特徵是:

  • 具有相同的作用域(即同一個類定義中);
  • 函式名字相同;
  • 引數型別、順序或數目不同(包括);
  • virtual 關鍵字可有可無。

覆蓋是指派生類重新實現(或者改寫)了基類的成員函式,其特徵是:

  • 不同的作用域(分別位於派生類和基類中);
  • 函式名稱相同;
  • 引數列表完全相同;
  • 基類函式必須是虛擬函式。
#pragma once

#include <iostream>

using namespace std;

// 展示了 Overload 和 Override

class Base
{
public
: void f(int x) { cout << "Base::f(int) " << x << endl; } // overload Base::f(int x) void f(float x) { cout << "Base::f(float) " << x << endl; } virtual void g(void) { cout << "Base::g(void)" << endl; } }; class Derived : public Base { public
: // override Base::g(void) virtual void g(void) { cout << "Derived::g(void)" << endl; } }; void test() { Derived d; Base *pb = &d; pb->f(42); // Base::f(int) 42 pb->f(3.14f); // Base::f(float) 3.14 pb->g(); // Derived::g(void) }

注:

  1. virtual 關鍵字告訴編譯器,派生類中相同的成員函式應該放到 vtable 中,並替換基類相應成員函式的槽位;
  2. 虛擬函式的覆蓋有兩種方式:完全重寫和擴充套件。擴充套件是指派生類虛擬函式首先呼叫基類的虛擬函式,然後在增加新的功能。

2. 令人迷惑的隱藏規則

隱藏是指派生類的成員函式遮蔽了與其同名的基類成員函式,具體規則如下:

  • 派生類的函式與基類的函式同名,但是引數列表有所差異,此時,不論有無 virtual 關鍵字,基類的函式在派生類中將被隱藏(注意別於過載混淆);
  • 派生類的函式與基類的函式同名,引數列表也相同,但是基類函式沒有 virtual 關鍵字。此時,基類的函式在派生類中將被隱藏(注意別與覆蓋混淆)。
#pragma once

#include <iostream>

using namespace std;

// 展示了 Override 和 Hide

class Base
{
public:
    virtual void f(float x) { cout << "Base::f(float) " << x << endl; }
    void g(float x) { cout << "Base::g(float) " << x << endl; }
    void h(float x) { cout << "Base::h(float) " << x << endl; }
};
class Derived : public Base
{
public:
    // override Base::f()
    virtual void f(float x) { cout << "Derived::f(float) " << x << endl; }
    // hide Base::g()
    void g(int x) { cout << "Derived::g(int) " << x << endl; }
    // hide Base::h()
    void h(float x) { cout << "Derived::h(float) " << x << endl; }
};

void test()
{
    Derived d;
    Base *pb = &d;
    Derived *pd = &d;
    // Good : behavior depends solely on type of the object
    pb->f(3.14f); // Derived::f(float) 3.14
    pd->f(3.14f); // Derived::f(float) 3.14
    // Bad : behavior depends on type of the pointer
    pb->g(3.14f); // Base::g(float) 3.14
    pd->g(3.14f); // Derived::g(int) 3 (surprise!)
    // Bad : behavior depends on type of the pointer
    pb->h(3.14f); // Base::h(float) 3.14 (surprise!)
    pd->h(3.14f); // Derived::h(float) 3.14
}

注:如果你確實想使用所謂的“跨越類邊界的過載”,可以在派生類定義中的任何地方顯示地使用 using 關鍵字,如下:

class Derived: public Base{
public:
    using Base::g;
    void g(int x) {...}
}

3. 擺脫隱藏

隱藏規則引起不少麻煩。下面程式碼中,程式設計師可能期望語句 pd->f(10) 呼叫 Base::f(int),但是 Base::f(int) 不幸被Derived::f(char) 隱藏了。由於數字 10 不能被隱式地轉換為字串型別,所以在編譯時出錯。

#pragma once

#include <iostream>

using namespace std;

// 展示了 Hide 所帶來的麻煩

class Base
{
public:
    void f(int x) { cout << x << endl; }
};
class Derived : public Base
{
public:
    // hide Base::f(int)
    void f(char *str) { cout << str << endl; }

    // 擺脫隱藏法一
    //using Base::f;

    // 擺脫隱藏法二
    //void f(int x) { Base::f(x); }
};

void test(void)
{
    Derived *pd = new Derived;
    pd->f(10); // error 編譯時報錯,因為Base中函式被隱藏
}

如果語句 pd->f(10) 確實想呼叫函式 Base::f(int),那麼有兩個辦法:其一就是使用 using 宣告;其二就是把類 Derived 修改為如下的樣子。

class Derived : public Base
{
public:
    // hide Base::f(int)
    void f(char *str) { cout << str << endl; }
    // 呼叫傳遞
    void f(int x) { Base::f(x); }
};

相關推薦

[C++]成員函式過載(overload)覆蓋(override)隱藏(hide)

C++成員函式的過載、覆蓋和隱藏 1. 過載與覆蓋 成員函式被過載的特徵是: 具有相同的作用域(即同一個類定義中); 函式名字相同; 引數型別、順序或數目不同(包括); virtual 關鍵字可有可無。 覆蓋是指派生類重新實現(或者改寫)了基

C++專題】過載(overload)覆蓋(override)隱藏(hide) 辨析

  寫正題之前,先給出幾個關鍵字的中英文對照,過載(overload),覆蓋(override),隱藏(hide)。在早期的C++書籍中,可能翻譯的人不熟悉專業用語(也不能怪他們,他們不是搞計算機程式設計的,他們是英語專業的),常常把過載(overload)和覆蓋(ov

C++學習之多型及過載(overload),覆蓋(override),隱藏(hide)的區別

C++程式語言是一款應用廣泛,支援多種程式設計的計算機程式語言。我們今天就會為大家詳細介紹其中C++多型性的一些基本知識,以方便大家在學習過程中對此能夠有一個充分的掌握。   多型性可以簡單地概括為“一個介面,多種方法”,程式在執行時才決定呼叫的函式,它是面向物件程式設計

C++多型及過載(overload),覆蓋(override),隱藏(hide)的區別

C++程式語言是一款應用廣泛,支援多種程式設計的計算機程式語言。我們今天就會為大家詳細介紹其中C++多型性的一些基本知識,以方便大家在學習過程中對此能夠有一個充分的掌握。   多型性可以簡單地概括為“一個介面,多種方法”,程式在執行時才決定呼叫的函式,它是面向物件程式設

C++基礎】過載overload重寫(覆蓋)override隱藏hide的區別

過載overload 過載是指不同的函式使用相同的函式名,但是函式的引數個數或型別不同。呼叫的時候根據函式的引數來區別不同的函式。 相同的範圍(在同一個類中)函式名字相同引數不同virtual可有可無編譯期繫結,與多型無關 重寫(覆蓋)override 重寫/覆蓋是在在

過載(Overloads)重寫(Overrides)隱藏(Shadows) 的區別及用法

過載、重寫和隱藏是很容易混淆的類似概念。雖然所有這三種技術都使您得以建立同名的成員,但它們之間有一些重要的差異。 過載的成員用於提供屬性或方法的不同版本,這些版本具有相同名稱但是接受不同數量的引數或者接受不同資料型別的引數。 重寫的屬性和方法用於替換在派生類中不適合的繼承的屬性

C++ 類成員函式過載(overload),重寫/覆蓋(override),隱藏

C++ 類層次中的同名函式,有三種關係: 過載(overload) 重寫、覆蓋(override) 隱藏(hide,oversee) 過載 c++函式過載 相同的範圍(在同一個類中)

c++ 成員函式過載覆蓋隱藏

成員函式的過載、覆蓋與隱藏 成員函式的過載、覆蓋(override)與隱藏很容易混淆,C++程式設計師必須要搞清楚 概念,否則錯誤將防不勝防。 8.2.1 過載與覆蓋 成員函式被過載的特徵: (1)相同的範圍(在同一個類中); (2)函式名字相同; (3)引數不同;

C++成員函式過載覆蓋隱藏

 成員函式的過載、覆蓋(override)與隱藏很容易混淆,C++程式設計師必須要搞清楚概念,否則錯誤將防不勝防。 成員函式被過載的特徵:(1)相同的範圍(在同一個類中);(2)函式名字相同;(3)引數不同;(4)virtual 關鍵字可有可無。 覆蓋:派生類函式覆蓋基類函式

c++ const在過載overload覆蓋override上使用區別

1.overload 過載 首先講講const在過載上的使用,過載的目的是為了根據不同的輸入來呼叫不同的同名函式。const的位置不同會引起不同的效果,我在一篇轉載文章中具體闡述過:點選開啟連結 再歸納一下,能否構成過載的區別在於使用者能否知曉函式的不同: 1)放在函式尾部

C++語言特性:建構函式,解構函式,虛擬函式,行內函數,靜態成員函式,過載覆蓋隱藏

C++中class預設屬性為private, struct預設屬性為public 建構函式:        1.初始化物件成員;        2.建立類物件;        由於虛擬函式是建立在物件的基礎上的,因此建構函式不能宣告為虛擬函式;虛擬函式是在執行的時候才識別,

C++中函式過載隱藏覆蓋重寫的區別 轉自:http://www.bijishequ.com/detail/277975?p=

程式碼編譯執行環境:VS2012+Debug+Win32 1.函式過載(Function Overload) 1.1定義 C++規定在同一作用域中,同名函式的形式引數(指引數的個數、型別或者順序)不同時,構成函式過載。 1.2用法 比如,要從兩個變數中返回其中較

Java中類成員函式過載覆蓋隱藏的區別

其他擴充套件連結: 過載: 成員函式被過載的特徵: 1)相同的範圍:在同一個類中 2)函式名相同,引數不同 3)virtual可有可無 覆蓋: 派生函式覆蓋基類函式 1)位於不同的範圍內(子類

C++ 過載運算子 運算子過載函式作為類成員函式 過載運算子+

用運算子過載函式作為類成員函式的方法過載運算子+ 下面的例子來自於課本: #include <iostream> using namespace std; class Complex {

函式過載(overload)函式重寫(override)的基本規則

本文由Markdown語法編輯器編輯完成。 1. 前言:   在C++中有兩個非常容易混淆的概念,分別是函式過載(overload)和函式重寫(overwirte)。雖然只相差一個字,但是它們兩者之間的差別還是非常巨大的。而通過深入瞭解這兩個概念的區別,

初識C++之函式過載重寫重定義的區別

在C++的學習中,慢慢接觸了一些很容易混淆的名詞,今天就來剖析幾個容易混淆的名詞。 1、函式過載   過載函式是函式的一種特殊情況,為方便使用,C++允許在同一範圍中宣告幾個功能類似的同名函式,但是這些同名函式的形式引數(指引數的個數、型別或者順序)必須不同

C++中過載重寫(覆蓋隱藏的區別例項分析

本文例項講述了C++中過載、重寫(覆蓋)和隱藏的區別,對於C++面向物件程式設計來說是非常重要的概念。具體分析如下: 1.過載:過載從overload翻譯過來,是指同一可訪問區內被宣告的幾個具有不同引數列(引數的型別,個數,順序不同)的同名函式,根據引數列表確定呼叫哪個函式,過載不關心函式返回型

C++基礎知識複習--運算子過載(非成員函式過載成員函式過載)

#include<iostream> using namespace std; class Complex { private: float Vector_x; float Vector

C#:區分:重寫覆蓋過載以及虛方法抽象方法

(一)重寫和覆蓋: 重寫: 在宣告時,父類的方法前面加上virtual關鍵字,子類的方法前面加上override關鍵字,且與父類方法同名,表示父類的方法可以被子類進行修改和重新定義。 覆蓋: 在宣告子類方法的時候,新增new關鍵字,定義與父類同名的方法,

C++中過載重寫(覆蓋隱藏的區別

基本概念: 過載:是指同一可訪問區內被宣告的幾個具有不同引數列(引數的型別,個數,順序不同)的同名函式,根據引數列表確定呼叫哪個函式,過載不關心函式返回型別。 示例: class A{ public: void test(int i); voi