C 深度剖析教程26 父子間的衝突

2021-08-15 22:26:48 字數 2501 閱讀 2899

今天繼續來學習c++,父類與子類之間的衝突。加qq1126137994共同學習交流。

子類中是否可以定義父類中的同名成員,如果可以,如何區分?如果不可以那又為什麼?

下面還是以乙個簡單的例子,來說明上述幾點的正確性

#include 

#include

using

namespace

std;

class parent

};class child : public parent

};int main()

執行結果為:

parent():&mi = 0xbfcfd2e8

child():&mi = 0xbfcfd2ec

&c.mi = 0xbfcfd2ec

c.mi = 100

&c.parent::mi = 0xbfcfd2e8

c.parent::mi = 1000

由執行結果知,建立的子類的c的成員變數mi的位址是與child類成員變數mi的位址相同的,而不是與父類parent的成員變數的位址相同。

而且呼叫父類的成員的方法是加上作用域的符號::。由以上程式以及執行結果,很容易就驗證了上述的幾條結論。

回顧過載的特性:

類中的成員函式可以進行過載

過載函式的本質為多個不同的函式

函式名和引數列表是唯一的標識

函式過載必須發生在同乙個作用域中

問題:

子類中定義的函式是否能過載父類中同名的函式

下面我們以乙個簡單的示例來說明問題:

#include 

#include

using

namespace

std;

class parent

void add(int a, int b)

};class child : public parent

};int main()

上述程式編譯是不通過的,顯示錯誤如下:

test.cpp: in function 『int main()』:

test.cpp:40: error: no matching function for call to 『child::add(int)』

test.cpp:24: note: candidates are: void child::add(int, int, int)

test.cpp:41: error: no matching function for call to 『child::add(int, int)』

test.cpp:24: note: candidates are: void child::add(int, int, int)

delphi@delphi-vm:~$ g++ test.cpp

由錯誤結果知,c.add(1); c.add(2,3);這兩個呼叫錯誤,子類中並沒有這個函式,為什麼呢?

因為子類的中的同名函式:add(int x,int y,int z),將子類從父類那裡繼承而來的兩個add函式給隱藏個了,現在子類物件只能看到乙個add(int x,int y,int z)函式,而無法呼叫繼承而來的兩個父類add()函式(相當於說明了子類無法過載父類的函式)。正確的呼叫方式為,加上作用域:

c.parent::add(1);

c.parent::add(2,3);

則上述程式的執行結果為:

c.mi = 100

c.parent::mi = 1000

c.mi = 115

c.parent::mi = 1006

這樣就對了!!!

那麼我如果在子類中定義與父類同名的函式,會發生什麼呢?

#include 

#include

using

namespace

std;

class parent

void add(int a, int b)

};class child : public parent

void add(int a, int b)

void add(int x,int y,int z)

};int main()

執行結果為:

c.mi = 100

c.parent::mi = 1000

c.mi = 121

c.parent::mi = 1000

由執行結果以及程式的分析可知,當子類中與父類定義完全相同的函式,是可行的,子類呼叫時,是呼叫子類的成員函式的,除非加上父類的作用域符,才會呼叫父類的成員函式。

結論:

子類中的函式將隱藏父類中的同名函式

子類無法過載父類中的成員函式

使用作用域分辨符來訪問父類的成員函式

子類可以定義與父類中完全相同的函式

C 父子類間的衝突(3) 多型

c 三大特性之一就是 多型 多型 咋一聽很高大上,其實是很容易理解的。我們先直白地理解 多型就是乙個事物有很多種狀態,帶入到c 中,結合之前對於重寫和過載的理解,我們是不是有理由懷疑函式過載就是c 中的一種多型?include stdio.h class parent class child pub...

C 深度剖析教程38 類模板深度剖析

類模板可以定義任意多個不同的型別引數 類模板可以被特化 類模板的特化型別 看 include include using namespace std template typename t1,typename t2 class test template typename t1,typename t...

C 父子類間的衝突(2) 賦值相容

父類和子類之間是繼承的關係,子類擁有父類的一切屬性 又有自己獨有的屬性。我們都知道把double賦給float會發生精度縮小的問題,那麼用子類物件去初始化父類物件會發生什麼呢?看下面一段 include stdio.h class parent class child public parent i...