huolong blog

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的那片空间.