h--------------------------
#ifndef VIRTUALFUNCTION_H
#define VIRTUALFUNCTION_H
/*
* 派生类中覆盖虚函数的使用知识点
* 1、返回值必须相同。 一个特例,返回值为本类类型的引用或指针,且可转为基类类型。
* 参见:
* virtual virtualFunction * own()
* double defaultChange() override
* float defaultChange() override
*
* 2、参数类型必须相同,参数个数必须相同,参数类型的顺序必须相同。
* 参见:
* void param(double, float, int) override
* void param(int, double, float) override
*
* 3、虚函数带有默认实参。
* a)基类指针或引用指向派生类对象,调用含有默认参数的虚函数时,在编译时静态绑定基类默认的实参值,而不是派生类的实参值。
* 此情况将与预期不符合,值得注意。
* 参见:
* virtual void defaultParam(int a = 10)
* void defaultParam(int a = 20) override
* pvf->defaultParam()
* b)派生类指针或引用,调用含有默认参数的虚函数时,也是编译时静态绑定基类默认的实参值,但绑定的是派生类的实参值。
* 参见:
* virtual void defaultParam(int a = 10)
* void defaultParam(int a = 20) override
* ppf->defaultParam()
*
* 4、回避虚函数,或者说,用指向派生类对象的基类指针或引用去调用基类版本的虚函数
* 参见:
* pvf->virtualFunction::own()
*
* ,或者说,在派生类中调用基类版本的虚函数
* 参见:
* void parentFunction::dieCircle()
*
* ,或者说,用派生类对象调用基类版本的虚函数
* 参见:
* ppf->virtualFunction::own()
*
* 5、C++11新增关键字override,在派生类中标识虚函数被覆盖。
* a)override可加可不加,添加override编译器可以帮我们检查重写的函数返回值和参数是否符合规则,不符合规则会报错。
* b)若不加override,把返回值或参数类型和顺序写错了,便不是覆盖,而是函数重载
* 参见:
* double defaultChange() override
*
* 6、C++11新增关键字final。final可修饰类和成员函数。
* a)被final修饰的类不可以用于派生基类。
* b)被final修饰的成员函数不可以在派生类中被覆盖。
* 参见:
* void finalVirtualFunc() override
* class parentClass: public finalClass
*/
class virtualFunction
{
public:
virtualFunction();
virtual virtualFunction * own();
virtual float defaultChange();
virtual void param(int, double, float);
virtual void defaultParam(int a = 10);
virtual void dieCircle();
virtual void finalVirtualFunc() final;
};
class parentFunction: public virtualFunction
{
public:
parentFunction * own() override; //正确
//double defaultChange() override; //报错 conflicting return type
float defaultChange() override; //正确
//void param(double, float, int) override; //报错 maked override, but does not override
void param(int, double, float) override; //正确
void defaultParam(int a = 20) override;
void dieCircle() override;
// void finalVirtualFunc() override; //错误 error overriding final function
};
class finalClass final
{};
//class parentClass: public finalClass //错误:cannot derive from 'final' base 'finalCalss' in derived type 'parentClass'
//{};
#endif // VIRTUALFUNCTION_H
main-----------------------
#include "virtualfunction.h"
#include "finalfix.h"
int main(void)
{
virtualFunction *pvf;
parentFunction *ppf;
pvf = new parentFunction();
ppf = new parentFunction();
pvf->own();
pvf->virtualFunction::own();
ppf->virtualFunction::own();
pvf->defaultChange();
pvf->param(0,0,0);
pvf->defaultParam();
ppf->defaultParam();
pvf->dieCircle();
// system("pause");
return 0;
}
打印输出---------------
i am parentFunction father...
i am virualFunction son...
i am virualFunction son...
i am father float...
i am father, my param order is int - double - float...
i am father, my default param value is 10 ...
i am father, my default param value is 20 ...
i am son circle...
i am father circle...
cpp-------------------
#include "virtualfunction.h"
#include <QDebug>
virtualFunction::virtualFunction()
{
}
virtualFunction *virtualFunction::own()
{
qDebug()<<"i am virualFunction son...";
}
float virtualFunction::defaultChange()
{
qDebug()<<"i am son float...";
}
void virtualFunction::param(int, double, float)
{
qDebug()<<"i am son , my param order is int - double - float...";
}
void virtualFunction::defaultParam(int a)
{
qDebug()<<"i am son, my default param value is "<<a<<"...";
}
void virtualFunction::dieCircle()
{
qDebug()<<"i am son circle...";
}
void virtualFunction::finalVirtualFunc()
{
qDebug()<<"i am son final function, i can't be override...";
}
parentFunction *parentFunction::own()
{
qDebug()<<"i am parentFunction father...";
}
void parentFunction::param(int, double, float)
{
qDebug()<<"i am father, my param order is int - double - float...";
}
void parentFunction::defaultParam(int a)
{
qDebug()<<"i am father, my default param value is "<<a<<"...";
}
void parentFunction::dieCircle()
{
// dieCircle(); //错误,自己调用自己是死循环
virtualFunction::dieCircle();
qDebug()<<"i am father circle...";
}
//void parentFunction::param(double, float, int)
//{
// qDebug()<<"i am father, my param order is double - float - int...";
//}
float parentFunction::defaultChange()
{
qDebug()<<"i am father float...";
}