一、父子之間的沖突:
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;
}
代碼是否可以編譯通過(guò),我們來(lái)看一下編譯器編譯的結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#
什么情況,居然可以編譯情況,但是你從肉眼看,你看出到底是父類mi還是子類的mi呢,顯然我們不能夠去瞎猜,那么接下來(lái)我們來(lái)學(xué)習(xí)里面的真理!
2、父子之間沖突的規(guī)則:
子類可以定義父類中的同名成員
子類中的成員將隱藏父類中的同名成員
父類中的同名成員依然存在于子類中
通過(guò)作用域分辨符(::)訪問(wèn)父類中的同名成員,例如:
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)觀察來(lái)看,函數(shù)重名和成員重名的作用一樣,子類會(huì)覆蓋父類的。
為了更加說(shuō)明這點(diǎn),我們?cè)賮?lái)看一個(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ù)
解決方案,就是利用作用域符分辨符解決問(wèn)題:
#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ù)
子類無(wú)法重載父類中的成員函數(shù)(不在同一作用域里面)
使用作用域分辨符訪問(wèn)父類中的同名函數(shù)
子類可以定義類中完全相同的成員函數(shù)
二、總結(jié)
子類可以定義父類中的同名成員
子類中的成員將隱藏父類中的同名成員
子類和父類中的函數(shù)不能構(gòu)造重載關(guān)系
子類可以定義父類中完全相同的成員函數(shù)
使用作用域分辨符訪問(wèn)父類中的同名成員或者函數(shù)
好了,今天的分享就到這里,如果文章中有錯(cuò)誤或者不理解的地方,可以交流互動(dòng),一起進(jìn)步。我是txp,下期見(jiàn)!
-
可編程邏輯
+關(guān)注
關(guān)注
7文章
526瀏覽量
45184 -
C++
+關(guān)注
關(guān)注
22文章
2120瀏覽量
76444
發(fā)布評(píng)論請(qǐng)先 登錄
IP地址沖突導(dǎo)致德國(guó)站群服務(wù)器斷網(wǎng)的解決方法?
C++ 與 Python:樹(shù)莓派上哪種語(yǔ)言更優(yōu)?

使用C++中的CyAPI編寫(xiě)的應(yīng)用程序上遇到了問(wèn)題,求解決
iic協(xié)議常見(jiàn)故障及解決方法
無(wú)功補(bǔ)償故障原因及解決方法
Spire.XLS for C++組件說(shuō)明

電子焊接的常見(jiàn)問(wèn)題及解決方法
同樣是函數(shù),在C和C++中有什么區(qū)別
伺服電機(jī)常見(jiàn)故障及解決方法有哪些
C7000 C/C++優(yōu)化指南用戶手冊(cè)

以太網(wǎng)組網(wǎng)常見(jiàn)故障及解決方法
TMS320C6000優(yōu)化C/C++編譯器v8.3.x

C語(yǔ)言和C++中結(jié)構(gòu)體的區(qū)別
C7000優(yōu)化C/C++編譯器

評(píng)論