一.重载
定义:发生在统一作用域中,函数名称相同,但是参数列表不同(包括参数的个数,参数类型,参数顺序)。
#include <iostream>
using std::cout;
using std::endl;
int add(int a,int b)
{
cout<<"this is int add(int a,int b)"<<endl;
return a+b;
}
double add(double a, double b)
{
cout<<"this is double add(double a, double b)"<<endl;
return a+b;
}
int add(int a,int b,int c)
{
cout<<"this is int add(int a,int b,int c)"<<endl;
return a+b+c;
}
int main()
{
int a=1,b=2,c=3;
cout<<"int add(int a,int b) = "<<add(a,b)<<endl;
cout<<"int add(int a,int b,int c) = "<<add(a,b,c)<<endl;
double aa=1.2,bb=2.2;
cout<<"double add(double a, double b) = "<<add(aa,bb)<<endl;
}
二.重写(覆盖)
定义:发生在基类与派生类中,必须是虚函数,函数名相同,参数列表也相同。可以通过override关键字判断是否是重写函数。
#include <iostream>
using std::endl;
using std::cout;
class Base
{
private:
int _ix;
public:
Base(int x=0)
:_ix(x)
{
cout<<"Base(int x=0)"<<endl;
}
~Base()
{
cout<<"~Base()"<<endl;
}
virtual
void print()const
{
cout<<"Base::_ix = "<<_ix<<endl;
}
};
class Derived
:public Base
{
private:
int _iy;
public:
Derived(int x=0,int y=0)
:Base(x)
,_iy(y)
{
cout<<"Derived(int x=0,int y=0)"<<endl;
}
~Derived()
{
cout<<"~Derived()"<<endl;
}
//经过继承下来此时print也是虚函数
void print()const
{
cout<<"Derived:: _iy = "<<_iy<<endl;
}
};
void func(Base* base)
{
base->print();
}
void test()
{
Base base(3);
Derived derived(33,44);
//同一个指令根据
func(&base);
func((Base*)&derived);
func(&derived);
}
int main()
{
test();
return 0;
}
如果加了override表示这个函数是继承基类的虚函数并且重写了基类的函数,因为重写时要保证函数名,函数类型,函数参数要完全相同,如果不同就会报错。
三.隐藏
定义:发生在基类与派生类中,派生类中的函数与基类的函数名字相同。(至于是不是虚函数,参数列表相不相同都没有关系),在派生类中会隐藏基类的同名函数和数据成员。
#include <iostream>
#include <string.h>
#include <stdio.h>
using std::cout;
using std::endl;
class Base
{
public:
char* _str;
Base(const char* str)
:_str(new char[strlen(str)+1]())
{
strcpy(_str,str);
cout<<"Base(const char* str)"<<endl;
}
virtual
~Base()
{
cout<<"~Base()"<<endl;
if(_str)
{
delete[]_str;
_str=nullptr;
}
}
void print() const
{
printf("Base::_str = %s\n",_str);
}
};
class Derived
:public Base
{
private:
char* _str;
public:
Derived(const char* str,const char* str1)
:Base(str)
,_str(new char[strlen(str1)+1]())
{
strcpy(_str,str1);
cout<<"Derived(const char* str,const char* str1)"<<endl;
}
~Derived()
{
cout<<"~Derived()"<<endl;
if(_str)
{
delete[]_str;
_str=nullptr;
}
}
void print() const
{
printf("Derived::_str = %s\n",_str);
//同名的数据成员也会被隐藏,如果要找到基类的数据成员需要特指加上作用域限定符
printf("Derived::Base::_str = %s\n",Base::_str);
}
};
int main()
{
Derived derived("基类","派生类");
derived.print();
//如果想要打印基类只能加上作用域限定符
derived.Base::print();
}
可以看出在继承时派生类会对基类的同名数据成员和成员函数进行隐藏,这也很好理解,如果没有隐藏就会有多个同名函数,这些同名函数可以完全相同这就使得无法区分,所以可以在派生类对象调用成员函数时将继承来的成员函数隐藏,防止出现二义性。