一、父子之間的沖突:
1、思考
子類中是否可以定義父類中的同名成員?
如果可以的話,那么該怎樣區分呢?
如果不可以的話,那么又是為啥呢?
代碼實踐:
#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;
}
代碼是否可以編譯通過,我們來看一下編譯器編譯的結果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#
什么情況,居然可以編譯情況,但是你從肉眼看,你看出到底是父類mi還是子類的mi呢,顯然我們不能夠去瞎猜,那么接下來我們來學習里面的真理!
2、父子之間沖突的規則:
子類可以定義父類中的同名成員
子類中的成員將隱藏父類中的同名成員
父類中的同名成員依然存在于子類中
通過作用域分辨符(::)訪問父類中的同名成員,例如:
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;
}
輸出結果:
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)類中的成員函數可以進行重載
重載函數的本質為多個不同的函數
函數名和參數列表是唯一的標識
函數重載必須發生在同一個作用域中,這一點非常關鍵
(2)子類中定義的函數是否能夠重載父類中的同名函數呢?
代碼實踐:
#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.add(1);
c.add(2, 3);
c.add(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
結果輸出:
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
注解:從實驗觀察來看,函數重名和成員重名的作用一樣,子類會覆蓋父類的。
為了更加說明這點,我們再來看一個示例:
#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.add(1);
c.add(2, 3);
c.add(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
編譯結果:
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.add(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.add(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)這兩個函數
解決方案,就是利用作用域符分辨符解決問題:
#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.add(4, 5, 6);
cout << "c.mi = " << c.mi << endl;
cout << "c.Parent::mi = " << c.Parent::mi << endl;
return 0;
}
輸出結果:
root@txp-virtual-machine:/home/txp# ./a.out
c.mi = 100
c.Parent::mi = 1000
c.mi = 115
c.Parent::mi = 1006
4、小結:
子類中的函數將隱藏父類的同名函數
子類無法重載父類中的成員函數(不在同一作用域里面)
使用作用域分辨符訪問父類中的同名函數
子類可以定義類中完全相同的成員函數
二、總結
子類可以定義父類中的同名成員
子類中的成員將隱藏父類中的同名成員
子類和父類中的函數不能構造重載關系
子類可以定義父類中完全相同的成員函數
使用作用域分辨符訪問父類中的同名成員或者函數
好了,今天的分享就到這里,如果文章中有錯誤或者不理解的地方,可以交流互動,一起進步。我是txp,下期見!
-
可編程邏輯
+關注
關注
7文章
516瀏覽量
44105 -
C++
+關注
關注
22文章
2110瀏覽量
73696
發布評論請先 登錄
相關推薦
評論