C++中的重写、隐藏与重载的区别
C++面向对象的一些易混淆概念
重写(覆盖):是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
隐藏:是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数且没有被virtual关键字修饰,不管参数列表是否相同,基类函数都会被隐藏。
重载:是指同一类中内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。 注:
- 重写和被重写的函数在不同的类中,隐藏函数和被隐藏函数在不同类中,重载和被重载的函数在同一类中.
- 重写与被重写的函数参数列表一定相同且必须有virtual修饰,重载和被重载的函数参数列表一定不同。
- 当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写。
#include<iostream>
using namespace std;
class base
{
public:
int x;
public:
base()
{
x = 100;
}
void func1()
{
cout << "base::func1调用"<<endl;
}
virtual void func2()
{
cout << "base::func2调用" << endl;
}
};
class sub : public base
{
public:
int x;
public:
sub()
{
x = 200;
}
void func1()
{
cout << "sub::func1调用" << endl;
}
virtual void func2()
{
cout << "sub::func2调用" << endl;
}
};
int main(int argc, char** argv)
{
sub b;
base * p1=&b;
p1->func1();
p1->func2();
cout << p1->x << endl;
sub* p2 = &b;
p2->func1();
p2->func2();
cout << p2->x << endl;
return 0;
}
输出结果:
base::func1调用
sub::func2调用
100
sub::func1调用
sub::func2调用
200
注意以上代码中定义基类和派生类中定义了同名变量x,在为子类对象分配空间时并没有将同名变量覆盖,而是分配了两个4字节,在用基类引用访问时访问时访问到了存有100的那片空间,而用子类访问时则访问到了存有200的那片空间.