一、父子之間的沖突:
1、思考
子類中是否可以定義父類中的同名成員?
如果可以的話,那么該怎樣區(qū)分呢?
如果不可以的話,那么又是為啥呢?
代碼實(shí)踐:
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
int mi;
};
class Child : public Parent
{
public:
int mi;
};
int main()
{
Child c;
c.mi = 100; // mi 究竟是子類自定義的,還是從父類繼承得到的?
return 0;
}
代碼是否可以編譯通過,我們來看一下編譯器編譯的結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#
什么情況,居然可以編譯情況,但是你從肉眼看,你看出到底是父類mi還是子類的mi呢,顯然我們不能夠去瞎猜,那么接下來我們來學(xué)習(xí)里面的真理!
2、父子之間沖突的規(guī)則:
子類可以定義父類中的同名成員
子類中的成員將隱藏父類中的同名成員
父類中的同名成員依然存在于子類中
通過作用域分辨符(::)訪問父類中的同名成員,例如:
Child c;
c.mi = 100; //子類中的mi
c.Parent::mi = 1000; // 父類中的mi
代碼實(shí)踐:
#include <iostream>
#include <string>
using namespace std;
namespace A
{
int g_i = 0;
}
namespace B
{
int g_i = 1;// 同名的全局變量,但是位于兩個(gè)不同的命名空間;
}
class Parent
{
public:
int mi;
Parent()
{
cout << "Parent() : " << "&mi = " << &mi << endl;
}
};
class Child : public Parent
{
public:
int mi;
Child()
{
cout << "Child() : " << "&mi = " << &mi << endl;
}
};
int main()
{
Child c;
c.mi = 100;
c.Parent::mi = 1000;
cout << "&c.mi = " << &c.mi << endl;
cout << "c.mi = " << c.mi << endl;
cout << "&c.Parent::mi = " << &c.Parent::mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
Parent() : &mi = 0x7ffc270e7bf0
Child() : &mi = 0x7ffc270e7bf4
&c.mi = 0x7ffc270e7bf4
c.mi = 100
&c.Parent::mi = 0x7ffc270e7bf0
c.Parent::mi = 1000
3、回顧重載:
(1)類中的成員函數(shù)可以進(jìn)行重載
重載函數(shù)的本質(zhì)為多個(gè)不同的函數(shù)
函數(shù)名和參數(shù)列表是唯一的標(biāo)識(shí)
函數(shù)重載必須發(fā)生在同一個(gè)作用域中,這一點(diǎn)非常關(guān)鍵
(2)子類中定義的函數(shù)是否能夠重載父類中的同名函數(shù)呢?
代碼實(shí)踐:
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
int mi;
void add(int v)
{
mi += v;
}
void add(int a, int b)
{
mi += (a + b);
}
};
class Child : public Parent
{
public:
int mi;
void add(int v)
{
mi += v;
}
void add(int a, int b)
{
mi += (a + b);
}
void add(int x, int y, int z)
{
mi += (x + y + z);
}
};
int main()
{
Child c;
c.mi = 100;
c.Parent::mi = 1000;
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
c.a(chǎn)dd(1);
c.a(chǎn)dd(2, 3);
c.a(chǎn)dd(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
結(jié)果輸出:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
c.mi = 100
c.Parent::mi = 1000
c.mi = 121
c.Parent::mi = 1000
注解:從實(shí)驗(yàn)觀察來看,函數(shù)重名和成員重名的作用一樣,子類會(huì)覆蓋父類的。
為了更加說明這點(diǎn),我們?cè)賮砜匆粋€(gè)示例:
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
int mi;
void add(int v)
{
mi += v;
}
void add(int a, int b)
{
mi += (a + b);
}
};
class Child : public Parent
{
public:
int mi;
void add(int x, int y, int z)
{
mi += (x + y + z);
}
};
int main()
{
Child c;
c.mi = 100;
c.Parent::mi = 1000;
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
c.a(chǎn)dd(1);
c.a(chǎn)dd(2, 3);
c.a(chǎn)dd(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
編譯結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:47:12: error: no matching function for call to ‘Child::add(int)’
c.a(chǎn)dd(1);
^
test.cpp:47:12: note: candidate is:
test.cpp:29:10: note: void Child::add(int, int, int)
void add(int x, int y, int z)
^
test.cpp:29:10: note: candidate expects 3 arguments, 1 provided
test.cpp:48:15: error: no matching function for call to ‘Child::add(int, int)’
c.a(chǎn)dd(2, 3);
^
test.cpp:48:15: note: candidate is:
test.cpp:29:10: note: void Child::add(int, int, int)
void add(int x, int y, int z)
^
test.cpp:29:10: note: candidate expects 3 arguments, 2 provided
注解:顯示匹配不到add(int)和add(int,int)這兩個(gè)函數(shù)
解決方案,就是利用作用域符分辨符解決問題:
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
int mi;
void add(int v)
{
mi += v;
}
void add(int a, int b)
{
mi += (a + b);
}
};
class Child : public Parent
{
public:
int mi;
void add(int x, int y, int z)
{
mi += (x + y + z);
}
};
int main()
{
Child c;
c.mi = 100;
c.Parent::mi = 1000;
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
c.Parent::add(1);
c.Parent::add(2, 3);
c.a(chǎn)dd(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# ./a.out
c.mi = 100
c.Parent::mi = 1000
c.mi = 115
c.Parent::mi = 1006
4、小結(jié):
子類中的函數(shù)將隱藏父類的同名函數(shù)
子類無法重載父類中的成員函數(shù)(不在同一作用域里面)
使用作用域分辨符訪問父類中的同名函數(shù)
子類可以定義類中完全相同的成員函數(shù)
二、總結(jié)
子類可以定義父類中的同名成員
子類中的成員將隱藏父類中的同名成員
子類和父類中的函數(shù)不能構(gòu)造重載關(guān)系
子類可以定義父類中完全相同的成員函數(shù)
使用作用域分辨符訪問父類中的同名成員或者函數(shù)
好了,今天的分享就到這里,如果文章中有錯(cuò)誤或者不理解的地方,可以交流互動(dòng),一起進(jìn)步。我是txp,下期見!
-
可編程邏輯
+關(guān)注
關(guān)注
7文章
527瀏覽量
45421 -
C++
+關(guān)注
關(guān)注
22文章
2124瀏覽量
77210
發(fā)布評(píng)論請(qǐng)先 登錄
keil實(shí)現(xiàn)c與c++混合編程
C編譯器錯(cuò)誤與解決方法
ODF配線架常見故障及解決方法?
C語(yǔ)言與C++的區(qū)別及聯(lián)系
C與C++之間的聯(lián)系
C語(yǔ)言和C++之間的區(qū)別是什么
C++之父親臨北京,AI原生時(shí)代最值得參加的系統(tǒng)軟件技術(shù)大會(huì)日程發(fā)布
C/C++條件編譯
C++程序異常的處理機(jī)制
IP地址沖突導(dǎo)致德國(guó)站群服務(wù)器斷網(wǎng)的解決方法?
ADC和FPGA之間LVDS接口設(shè)計(jì)需要考慮的因素
C++ 與 Python:樹莓派上哪種語(yǔ)言更優(yōu)?
主流的 MCU 開發(fā)語(yǔ)言為什么是 C 而不是 C++?
C++之父子之間沖突的解決方法
評(píng)論