前端学C++

316 阅读2分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

C++多态

C++的多态被称为三大特性之一,被概括为“一个接口,多种方法”,它是面向对象编程领域的核心概念。事实上,当我看到多态这个概念后,立马发现自己曾在JSTS代码实践中接触过它,实习中常见基类声明一个方法,但并不具体实现,在不同的子类中,对这个方法进行不同的实现。除了这种思想外,C++中的多态还涉及许多语言层级和编译的细节。

实现多态的两种方式:

  • 在子类中重写基类方法(Override
  • 使用virtual关键字 对于第一种方法要注意的是,重写也即Override是在类实现中重载类成员函数和虚函数(不同的函数参数列表,多个同名函数共存),不是在类声明时重新写这些函数,这样的操作被称为隐藏,即后面的实现覆盖了前面的实现,来个例子:
class Base
{
public:
	virtual void f(float x)
	{
		cout<<"Base::f(float)"<< x <<endl;
	}
	void g(float x)
	{
		cout<<"Base::g(float)"<< x <<endl;
	}
	void h(float x)
	{
		cout<<"Base::h(float)"<< x <<endl;
	}
};
class Derived : public Base
{
public:
	virtual void f(float x)
	{
		cout<<"Derived::f(float)"<< x <<endl;   //多态、覆盖
	}

	void g(int x) 
	{
		cout<<"Derived::g(int)"<< x <<endl;     //隐藏
	}
	void h(float x)
	{
		cout<<"Derived::h(float)"<< x <<endl;   //隐藏
	}
};

关于函数隐藏和virtual的关系,更详细的见此文

回到多态上来,上面两种多态的实现分别对应不同的绑定方式:

  • 通过重载函数实现:先期联编 static binding
  • 通过虚函数实现 :滞后联编 dynamic binding 解释一下函数的绑定何意:如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态绑定,也称早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于动态(晚)绑定。