一、父子之間的沖突:
1、思考
子類中是否可以定義父類中的同名成員?
如果可以的話,那么該怎樣區(qū)分呢?
如果不可以的話,那么又是為啥呢?
代碼實踐:
#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
代碼實踐:
#include <iostream>
#include <string>
using namespace std;
namespace A
{
int g_i = 0;
}
namespace B
{
int g_i = 1;// 同名的全局變量,但是位于兩個不同的命名空間;
}
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ì)為多個不同的函數(shù)
函數(shù)名和參數(shù)列表是唯一的標(biāo)識
函數(shù)重載必須發(fā)生在同一個作用域中,這一點非常關(guān)鍵
(2)子類中定義的函數(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ù)重名和成員重名的作用一樣,子類會覆蓋父類的。
為了更加說明這點,我們再來看一個示例:
#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)這兩個函數(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ù)
好了,今天的分享就到這里,如果文章中有錯誤或者不理解的地方,可以交流互動,一起進(jìn)步。我是txp,下期見!
-
可編程邏輯
+關(guān)注
關(guān)注
7文章
516瀏覽量
44123 -
C++
+關(guān)注
關(guān)注
22文章
2113瀏覽量
73742
發(fā)布評論請先 登錄
相關(guān)推薦
評論