重载
函数重载满足条件:
- 同一个作用域下
- 函数名称相同
- 函数参数类型不同 或者 个数不同 或者 顺序不同
注意: 函数的返回值不可以作为函数重载的条件。
#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");
}
如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏父类中所有版本的同名成员函数。
问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?
- 访问子类同名成员 直接访问即可
- 访问父类同名成员 需要加作用域