今天繼續來學習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...