成员函数的重载,覆盖和隐藏是三个很容易混淆的概念,下面我们来区分一下这三者
一 重载的特点
1 两个函数处于同一作用域中(即同一个类中)
2 函数名要相同
3 参数不相同(参数的个数,参数的类型,参数的顺序)
4 返回值可同可不同
5 virtual关键字可有可无
二 覆盖(重写)的特点
1 两个在不同作用域中(基类与派生类)
2 函数名相同
3 参数相同
4 基类必须要有virtual关键字
5返回值类型相同(除了协变)
此时基类的该函数被派生类的同名函数覆盖
三 隐藏的特点
1 两个函数处于不同的作用域中(基类与派生类)
2 函数名相同但是参数不同,无论有无virtual,基类的函数被派生类的同名函数隐藏
3 函数名相同,参数相同,基类中该函数没有virtual关键字,基类的函数被派生类的同名函数隐藏
下面看个例子体会下隐藏和覆盖的区别:
class Base
{
public:
Base(int x)
{
a = x;
}
virtual void f1()
{
cout <<a<<" "<< "Base::f1 ()" << endl;
}
int f2()
{
cout << a << " " << "Base::f2() " << endl;
return 0;
}
void f3()
{
cout << a << " " << "Base::f3() " << endl;
}
virtual Base*f4() //协变,还可为 virtual Base&f4()
{
cout << a << " " << "Base::f4()" << endl;
return this;
}
private:
int a;
};
class Derived :public Base
{
public:
Derived(int x, int y) :Base(x), b(y){}
virtual void f1()
{
cout << b << " " << "Derived::f1 () " << endl;
}
void f2()
{
cout << b << " " << "Derived::f2() " << endl;
}
void f3(int)
{
cout << b << " " << "Derived::f3()" << endl;
}
virtual Derived*f4() //协变还可为virtual Derived&f4()
{
cout << b << " " << "Derived::f4()" << endl;
return this;
}
private:
int b;
};
int main()
{
Base b(1);
Derived d(2, 3);
Base*pb = &b;
pb->f1();// 1 Base :: f1()
pb->f2();// 1 Base :: f2()
pb->f3();// 1 Base :: f3()
pb->f4();// 1 Base :: f4()
pb = &d;
pb->f1();//3 Derived :: f1()
pb->f2();//2 Base :: f2()
pb->f3();//2 Base :: f3()
pb->f4();//3 Derived :: f4()
return 0;
}
Derived 中f1,f4函数重写了Base中f1,f4
f2,f3隐藏了Base中f2,f3