C++子類物件隱藏了父類的同名成員函式(隱藏篇)
阿新 • • 發佈:2019-02-04
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
/**
* 定義人類: Person
* 資料成員: m_strName
* 成員函式: attack()
*/
class Person
{
public:
Person()
{
cout<<"Person()"<<endl;
}
Person(const Person& p)
{
cout<<"Person(const Person& p)"<<endl;
}
string m_strName;
void attack()
{
cout << "attack" << endl;
}
};
/**
* 定義士兵類: Soldier
* 士兵類公有繼承人類
* 資料成員: m_strName
* 成員函式: attack()
*/
class Soldier:public Person
{
public:
Soldier()
{
cout<<"Soldier()"<<endl;
}
string m_strName;
void attack()
{
cout << "fire!!!" << endl;
}
};
int main(void)
{
// 例項士兵物件
Soldier soldier;//例項化子類,會先呼叫基類建構函式,再呼叫子類的建構函式,析構時,則相反,先析構子類的,再析構基類的
Person p = soldier;//可以看出子類的物件可以初始化基類的物件,並且這種方式會呼叫基類的拷貝建構函式
// 向士兵屬性賦值"tomato"
soldier.m_strName = "tomato";
// 通過士兵物件向人類屬性賦值"Jim"
soldier.Person::m_strName = "Jim";
// 列印士兵物件的屬性值
cout << soldier.m_strName << endl;
// 通過士兵物件列印人類屬性值
cout << soldier.Person::m_strName << endl;//注意這種使用子類的物件呼叫基類成員變數的方式
// 呼叫士兵物件方法
soldier.attack();
// 通過士兵物件呼叫人類方法
soldier.Person::attack();//注意這種使用子類的物件呼叫基類的成員函式的方式
return 0;
#include <stdlib.h>
#include <string>
using namespace std;
/**
* 定義人類: Person
* 資料成員: m_strName
* 成員函式: attack()
*/
class Person
{
public:
Person()
{
cout<<"Person()"<<endl;
}
Person(const Person& p)
{
cout<<"Person(const Person& p)"<<endl;
}
string m_strName;
void attack()
{
cout << "attack" << endl;
}
};
/**
* 定義士兵類: Soldier
* 士兵類公有繼承人類
* 資料成員: m_strName
* 成員函式: attack()
*/
class Soldier:public Person
{
public:
Soldier()
{
cout<<"Soldier()"<<endl;
}
string m_strName;
void attack()
{
cout << "fire!!!" << endl;
}
};
int main(void)
{
// 例項士兵物件
Soldier soldier;//例項化子類,會先呼叫基類建構函式,再呼叫子類的建構函式,析構時,則相反,先析構子類的,再析構基類的
Person p = soldier;//可以看出子類的物件可以初始化基類的物件,並且這種方式會呼叫基類的拷貝建構函式
// 向士兵屬性賦值"tomato"
soldier.m_strName = "tomato";
// 通過士兵物件向人類屬性賦值"Jim"
soldier.Person::m_strName = "Jim";
// 列印士兵物件的屬性值
cout << soldier.m_strName << endl;
// 通過士兵物件列印人類屬性值
cout << soldier.Person::m_strName << endl;//注意這種使用子類的物件呼叫基類成員變數的方式
// 呼叫士兵物件方法
soldier.attack();
// 通過士兵物件呼叫人類方法
soldier.Person::attack();//注意這種使用子類的物件呼叫基類的成員函式的方式
return 0;
}
輸出結果:
Person() Soldier() Person(const Person& p) tomato Jim fire!!! attack
通過上面的例子,對於基類和子類之間的特性可以做如下的總結:
(1)當子類中含有和基類同名的成員變數時,再用子類的物件呼叫該同名成員變數時,將只會呼叫到子類自身定義的成員變數,而不會呼叫到基類的同名成員變數,這種現象就叫做隱藏,子類把基類的同名成員變數隱藏了,正確呼叫方式如上面例子中橘色字型部分:soldier.Person::m_strName;
(2)當子類中含有和基類同名的成員函式時,再用子類的物件呼叫該同名成員函式時,將只會呼叫到子類自身定義的成員函式,而不會呼叫到基類定義的同名的成員函式,這也是因為子類把基類的同名成員函式隱藏了;正確呼叫方法應該是如上面例子中橘色字型部分:soldier.Person::attack();
這裡要強調的是何為同名成員函式,即不管引數是否相同、返回值是否相同,只要函式名稱相同,就是同名成員函式,如果子類和基類定義了這樣的函式,子類就會把基類的相應函式隱藏掉。在上面的例子中加入我們在基類Person的attack()函式裡面新增引數int x,這個時候用soldier.attack(5)這種方式試圖呼叫基類的attack()仍然會報錯,是呼叫不到的。