覆盖体现在C++类中,我们平时叫做重写,比如重写某某某的虚函数。
虚函数:父类中加上了virtual关键字的成员方法(成员函数)叫做虚函数。
嗯,此文章针对入门级学习者,大牛请绕道。
一、覆盖
覆盖的前提条件:被重写的(父类函数)必须是虚函数。
覆盖:当子类中定义了一个与父类完全一样的虚函数时,就叫做子类重写了父类的虚函数,这就叫覆盖。
虚函数的两种体现方式:
- 普通重写
子类中定义了与父类完全一样的虚函数,包括返回值,函数名,函数参数(类型,个数)都相同时,也就构成了重写或者覆盖。 - 协变重写
子类中定义了与父类相同的虚函数,出了返回值,其他都相同时,父类返回值返回的是父类的指针或者引用,子类的返回值返回的是子类的指针或者引用。也构成了重写或者覆盖,这就是协变。
二、两种重写下面代码实现以下:
- 普通重写
#include <iostream>
#include <string> //string头文件
using namespace std;
class Cain
{//类内没有权限之分
public:
virtual void test(int age) //父类虚函数
{
cout << "Cain" << age << "岁"<<endl;
} //虚函数
protected:
int age;
};
class Beck : public Cain
{
public:
virtual void test(int age) //子类虚函数
{
cout << "Beck"<< age << "岁" << endl;
}//虚函数
protected:
int age;
};
void fun(Cain* p,int age)
{
p->test(age);
}
void fun(Cain& c,int age)
{
c.test(age);
}
int main()
{
Cain c;
Beck b;
fun(&c,23); //对象指针,result:Cain23岁
fun(&b,37); //对象指针,result:Beck37岁
fun(c,23); //对象引用,result:Cain23岁
fun(b,37); //对象引用,result:Beck37岁
system("pause");
return 0;
}
运行结果(验证是否正确):
ps:相机有点问题,因为公司电脑加密,有些东西不能截图,只能手机拍照了,见谅!
看来代码确实没有问题。
Ps: 子类重写父类虚函数时,virtual关键字其实可写可不写,写了更好,不写也没错,不过建议写着,习惯好点,别人阅读代码也觉得舒服一些。
- 协变重写
协变我们就在上面的基础上略做修改。
#include <iostream>
#include <string> //string头文件
using namespace std;
class Cain
{//类内没有权限之分
public:
virtual Cain* test(int age) //父类虚函数
{
cout << "Cain" << age << "岁"<<endl;
return this;
} //虚函数
protected:
int age;
};
class Beck : public Cain
{
public:
virtual Cain* test(int age) //子类虚函数
{
cout << "Beck"<< age << "岁" << endl;
return this; //返回this指针,this指针,后面花时间写一章。
}//虚函数
protected:
int age;
};
void fun(Cain* p,int age)
{
p->test(age);
}
void fun(Cain& c,int age)
{
c.test(age);
}
int main()
{
Cain c;
Beck b;
fun(&c,23); //对象指针,result:Cain23岁
fun(&b,37); //对象指针,result:Beck37岁
fun(c,23); //对象引用,result:Cain23岁
fun(b,37); //对象引用,result:Beck37岁
system("pause");
return 0;
}
运行结果:
亲测没有问题,大家可以试一下。
PS:如果返回值是引用,记得this要改变为*this,因为this指针是个地址,都懂的。这里就不唠叨了。
好了,覆盖就讲完了,当然,可能并不全面,但是有些东西需要自己结合实际去学习。
原创不易,觉得有帮助点个赞呗!
转载请注明出处。谢谢配合。