C++子类对象隐藏了父类的同名成员函数(隐藏篇) https://blog.csdn.net/alpha_love/article/details/75222175

https://blog.csdn.net/alpha_love/article/details/75222175

#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;

}

输出结果:

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()仍然会报错,是调用不到的。

猜你喜欢

转载自blog.csdn.net/sinat_35297665/article/details/81043593
今日推荐