重载
函数重载满足条件:
- 同一个作用域下
- 函数名称相同
- 函数参数类型不同 或者 个数不同 或者 顺序不同
注意: 函数的返回值不可以作为函数重载的条件。
#include<bits/stdc++.h>using namespace std;class A
{void fun() {};void fun(int i) {};void fun(int i, int j) {};
};
重载是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
重写(覆写)
重写(覆盖)是指派生类函数覆盖基类函数,特征是:
- 不同的范围,分别位于基类和派生类中
- 函数的名字相同,参数列表相同,返回值类型相同
- 基类函数必须有virtual关键字
多态使用方法:父类指针或引用指向子类对象。
#include<bits/stdc++.h>using namespace std;class A
{
public:virtual void fun(){cout << "A";}
};
class B :public A
{
public:virtual void fun(){cout << "B";}
};
int main(void)
{A* a = new B();a->fun();//输出B
}
重写发生在多态下,特指被virtual修饰的虚函数。重写是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。
重定义(隐藏)
重定义(隐藏)是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
- 基类函数没有virtual关键字
- 派生类的函数与基类的函数同名
class Base {
public:Base(){m_A = 100;}void func(){cout << "Base - func()调用" << endl;}void func(int a){cout << "Base - func(int a)调用" << endl;}public:int m_A;
};class Son : public Base {
public:Son(){m_A = 200;}//子类的func()函数会隐藏掉 父亲中所有叫 func 的函数,包括重载的版本。void func(){cout << "Son - func()调用" << endl;}
public:int m_A;
};void test01()
{Son s;cout << "Son下的m_A = " << s.m_A << endl;//如果子类想访问父类中被隐藏的同名成员,需要加父类的作用域cout << "Base下的m_A = " << s.Base::m_A << endl; cout << "---------------------------- " << endl;s.func(); // 直接调用 调用是子类中的同名成员s.Base::func(); // 如何调用父类中同名成员函数?加类名作用域。//如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏父类中所有版本的同名成员函数。//s.func(10); //这里是把父类的同名函数隐藏了,但子类却没有实现带参数版本的func函数。所以出错。s.Base::func(10);}
int main() {test01();system("pause");
}
如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏父类中所有版本的同名成员函数。
问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?
- 访问子类同名成员 直接访问即可
- 访问父类同名成员 需要加作用域