1.覆盖,重载,隐藏
重载:同一区域
//函数名相同
//参数列表不同
//virtual可以有,也可以没有
//返回值可以不同
隐藏:不同区域(子类与父类)
//函数名相同
//参数列表相同 + 不能有virtual
//参数列表不相同 ,可以有virtual,也可以没有virtual
//返回值可以不同
重写(覆盖):不同区域(子类与父类)
//函数名相同,参数列表相同,返回值相同
//基类中的方法 + virtual
//基类中的方法 不能加static
#include <iostream>
using namespace std;
//抽象类:包含纯虚函数的类
//1、不能定义对象,用于继承使用
//2、可以包含普通成员方法
//3、可以包含静态成员
//4、派生类必须重写抽象类的所有纯虚函数
class A
{
public:
//构造函数不允许加 virtual
//virtual A() = 0;
//error: constructors cannot be declared ‘virtual’
A(){};
//构造函数重载,不能有返回值
A(int val){
this->val = val;
}
//析构函数不允许重载,不能有参数、返回值,可+virtual
//虚析构,避免在特殊情况下不能正常执行子类析构
//特殊情况之一:父类指针指向子类对象
virtual ~A() = 0;
//~A(){};
//函数重载
string overloaded_func(string str){
cout<<"father 重载 str"<<endl;
this->str = str;
return str;
}
int overloaded_func(int val){
cout<<"father 重载 val"<<endl;
this->val = val;
return val;
}
//纯虚函数:为了实现多态
virtual int overloaded_func() = 0;
//函数重载完
//函数重写(覆盖)
//error: member ‘coverage_func’ cannot be declared both ‘virtual’ and ‘static’
virtual int coverage_func(int val){
cout<<"father 重写(覆盖) val"<<endl;
this->val = val;
return val;
}
//函数隐藏1,不同区域,除了覆盖便是隐藏
string hidden_func(string str){
cout<<"father 隐藏 str"<<endl;
this->str = str;
val = 10;
n = 9;
return str;
}
//函数隐藏2
virtual string hidden_func2(string str,int val){
cout<<"father 隐藏 virtual + str"<<endl;
this->str = str;
this->val = val;
return str;
}
private:
int val;
string str;
static int n;
};
A::~A(){
}
//继承
class B:public A
{
public:
B(){}
B(int max){
this->max = max;
data = new char [max];
}
~B(){
delete [] data;
}
//派生类重写纯虚函数
int overloaded_func(){
cout<<"派生类重写纯虚函数"<<endl;
return val;
}
int coverage_func(int val){
cout<<"覆盖父类函数"<<endl;
this->max = val;
return max;
}
//函数隐藏1
string hidden_func(string str){
cout<<"child 隐藏 str"<<endl;
this->str = str;
return str;
}
//函数隐藏2
int hidden_func2(int val){
cout<<"child 隐藏 virtual + int"<<endl;
this->val = val;
return val;
}
private:
int val;
char *data;
int max;
string str;
};
int main(void)
{
/*
A obj;
obj.overloaded_func(3);
error:cannot declare variable ‘obj’ to be of abstract type ‘A’
because the following virtual functions are pure within ‘A’
*/
A *ptr = new B;
ptr->overloaded_func("world");
/*
* 这里便体现了虚析构的重要性:继承、多态、父类指针指向子类对象、new
father 重载 str
派生类重写纯虚函数
覆盖父类函数
child 隐藏 str
child 隐藏 virtual + int
free(): invalid pointer
已放弃 (核心已转储)
*/
delete ptr;
B obj(10);
//重写纯虚函数
obj.overloaded_func();
//重写父类函数
obj.coverage_func(3);
//函数隐藏
obj.hidden_func("hello");
obj.hidden_func2(3);
return 0;
}
注意:如果继承的话,不建议基类的析构函数写成纯虚函数,这样会导致析构函数“未定义的 引用” ,因为基类的析构函数不能被重写,派生类有自己的析构函数,这时候便会报错。
还有就是定义B的对象时,如果没这么定义 obj(10),而是定义为 B obj,会导致析构函数删除失败,由于没有开辟空间,也就是已放弃(核心已转储)