重载、重写、重定义——三种同名函数的不同处理方式

2020-08-28 03:35:01 浏览数 (1)

重载、重写、重定义的区别:
重载

一个类中的重名函数,由于函数参数个数/类型的不同(形参列表不同),导致使用不同的函数进行处理,这种情况称为重载

代码语言:javascript复制
class A
{
	public:
		void show(){
			cout << "show()" << endl;
		}
		void show(int x){
			cout << "show(int x):"<< x << endl;
		}
};
int main(){
	A a;
	a.show();
	a.show(3);
}

对于重载函数,想调用哪个函数,取决于你给的参数。运行结果如下:

重定义(隐藏)
情况一
  • 如果同名函数在不同的类中,则他们不再是重载函数,
  • 若他们的形参列表不同,则基类中的同名函数将被隐藏(屏蔽)
代码语言:javascript复制
class A
{
public:
	void show(){
		cout << "A--show()" << endl;
	}
};
class B : public A
{
public:
	void show(int x){
		cout << "B--show()" << x << endl;
	}
};
int main(){
	B a;
	//a.show();
	//此时基类中的show()和子类中的函数同名而参数不同,
	//满足隐藏的条件,子类从基类继承而来的没有参数的
	//show()已经被隐藏了,无法调用
	a.A::show();
	a.show(5);
	system("pause");
	return 0;
}
情况二
  • 同名函数在不同的类中、参数相同,且基类中的同名函数前没有virtual关键字声明,那么基类中的同名函数依然会被隐藏。
代码语言:javascript复制
class A
{
	public:
		/* virtual */void show(){
			cout << "A--show()" << endl;
		}
};
class B : public A
{
	public:
		void show(){
			cout << "B--show()" << endl;
		}
};
int main(){
	B a;
	a.show();
	system("pause");
	return 0;
}
代码语言:javascript复制
class A
{
	public:
		/* virtual */void show(){
			cout << "A--show()" << endl;
		}
};
class B : public A
{
	public:
};
int main(){
	B a;
	a.show();
	system("pause");
	return 0;
}

对照上边两个程序:

  • 当子类中有与基类同名的参数,并且没有virtual修饰就构成隐藏
  • 当子类中拥有与父类相同函数名的函数时,子类对象在调用该函数时,会首先去子类中查找实现方式,如果子类中有实现,则执行子类函数,如果子类函数没有实现,然后去调用父类函数。
重写(覆盖)
  • 如果同名函数在不同的类中、参数相同、基类中的同名函数带有virtual关键字声明,这时基类中的同名函数将被重写(覆盖),它有以下两个特点:

①当对象调用子类中的同名函数时,表现和被隐藏时相同,程序结果不变(但其实和隐藏是不同的);

代码语言:javascript复制
class A
{
public:
	virtual void show(){
		cout << "A--show()" << endl;
	}
};
class B : public A
{
public:
	void show(){
		cout << "B--show()" << endl;
	}
};
int main(){
	A a;
	B b;
	a.show();
	b.show();
	system("pause");
	return 0;
}

②当通过指针或引用调用子类中的同名函数时,由于需要区别指针(引用)的类型和指针(引用)所指对象的类型,此时的表现就和隐藏不同了——通过基类指针指向不同对象,指针会根据对象的类型不同,调用其相应的函数。

代码语言:javascript复制
class A
{
public:
	virtual void show(){
		cout << "A--show()" << endl;
	}
};
class B : public A
{
public:
	void show(){
		cout << "B--show()" << endl;
	}
};
void fun(A* p){
	p->show();
}
int main(){
	A a;
	B b;
	fun(&a);
	fun(&b);
	system("pause");
	return 0;
}

一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中, 虚函数表也简称虚表。

运行结果:

0 人点赞