C++多态性——(2)联编

2024-01-03 01:40:31

归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏? + 留言?📝
成功的秘诀就在于多努力一次!

一起加油!

目录

一、前言:

二、静态联编:?

💦例:静态联编带来的一些问题的示例。

🔑说明:

三、动态联编:??

四、总结:

五、共勉:


一、前言:

????????多态从实现的角度可以划分为两类:编译时的多态和运行时的多态。编译时的多态是在编译的过程中确定了同名函数具体调用哪一个;而运行时的多态则是在程序运行过程中才动态地确定同名函数具体调用哪一个。这种确定调用具体代码段的过程就是联编。联编就是指计算机程序自身彼此关联的过程:即把一个源程序经过编译、连接,使之成为可执行的程序文件的过程。在这个过程中,计算机程序自身彼此关联,即将函数名和函数体联系在一起,将标识符名和存储地址联系在一起。用面向对象的术语讲,就是把消息和对象的方法相结合的过程。根据联编进行的阶段的不同,可以将其划分为静态联编和动态联编。这两种联编过程分别对应着多态的两种实现方式。

二、静态联编:?

????????静态联编支持的多态性,我们将其称为编译时的多态性,又称为静态的多态性,因为联编的过程是在程序开始执行之前进行的在编译、连接的过程中,系统可以根据类型匹配等特征确定程序中调用与具体执行函数的关系,即在哪个地方调用什么函数,此时的多态性就被称为编译时的多态性。

????????编译时的多态性可以通过函数重载来实现。函数重载的意义在于它可以用同一个名字访问一组相关的函数,能使用户为某一类操作取一个通用的名字。编译程序在编译时决定选择具体的函数段执行,这种方式也利于解决程序的复杂性。一般的函数和成员函数,构造函数都可以重载。

????????C++中通过两种工作方式实现编译的的多态性:函数重载和运算符重载。它们都属于静态联编。

????????静态联编函数调用速度快、效率较高,但是编程不灵活。

💦例:静态联编带来的一些问题的示例。

#include<iostream>
using namespace std;
class Space
{
	private:
		int x;
		int y;
	public:
		Space(int px,int py):x(px),y(py)
		{
			cout<<"Space construct called"<<endl;	
		}	
		double GetArea()
		{
			return 0;
		}
};
class Rectangle:public Space
{
	private:
		double w;
		double h;
	public:
		Rectangle(int px,int py,double pw,double ph):Space(px,py),w(pw),h(ph)
		{
			cout<<"Rectangle construct called"<<endl;
		}
		double GetArea()
		{
			return w*h;
		}
};
class Circle:public Space
{ 
	private:
		int r;
	public:
		Circle(int px,int py,int pr):Space(px,py),r(pr)
		{
			cout<<"Circle construct called"<<endl;
		}	
		double GetArea()
		{
			return 3.14*r*r;	
		}
};
int main(){
	Rectangle r1(30,40,4,8);
	Circle cr(30,40,4);
	Space *p=&r1;
	cout<<r1.GetArea()<<endl;
	cout<<p->GetArea()<<endl;
	p=&cr;
	cout<<cr.GetArea()<<endl;
	cout<<p->GetArea()<<endl;
	return 0;
}

🔑说明:

????????根据之前的内容,(1)在构造派生类 Rectangle 对象r1之前,首先会调用基类Shape的构造函数,因此先输出“Shape construct?called”,再输出“Rectangle construct called”,构造Circle 类对象cr 也是如此;(2)根据之前介绍的类型兼容性规则,其类指针p,可以指向不同的公有派生类对象,这里指向r1和cr。但是由于程序中完成的是静态联编,在程序编译阶段,基类指针p对于GetArea 方法的调用只能绑定到基类的 GetArea方法上,虽然程序运行时p指向了不同的派生类对象,但由于绑定过程在编译阶段已经完成,所以无论运行时p指向什么类型的对象始终调用的都是基类中的GetArea 方法,因此这种联编方式输出的结果不是我们期望的结果。?

????????关于类型兼容原则,在实际应用时需要注意以下几个方面。
(1)基类的指针可以指向它的公有派生类的对象,但是不允许指向它的私有派生类的对象。

(2)派生类的指针不允许指向它基类的对象。

(3)基类的指针指向它的公有派生类的对象时,只能用它来直接访问派生类中从基类继承来的成员,而不能直接访问公有派生类中定义的新成员。

三、动态联编:??

????????从上例中可得知有些联编工作不能在编译阶段完成,只有在序运行时才可以确定将要调用的函数。与静态联编相对应,这种绑定工作在程序运行阶段完成,被称为动态联编,又被称为动态绑定。
????????动态联编支持性,我们称的多态之为运行时的多态性,也称为动态多态性。在 C++中,运行的多态性,就是动态联编。动态联编提高了编程的灵活性和程序的易维护性,但与静态联编相比,函数调用速度慢。

四、总结:

  • 多态从实现的角度可以划分为两类:编译时的多态和运行时的多态。
  • 确定调用具体代码段的过程就是联编。
  • 联编就是指计算机程序自身彼此关联的过程:即把一个源程序经过编译、连接,使之成为可执行的程序文件的过程。
  • 根据联编进行的阶段的不同,可以将其划分为静态联编和动态联编。
  • 函数重载的意义在于它可以用同一个名字访问一组相关的函数,能使用户为某一类操作取一个通用的名字。
  • 一般的函数和成员函数,构造函数都可以重载。
  • C++中通过两种工作方式实现编译的的多态性:函数重载和运算符重载。它们都属于静态联编。
  • 静态联编函数调用速度快、效率较高,但是编程不灵活。
  • 基类的指针可以指向它的公有派生类的对象,但是不允许指向它的私有派生类的对象。

  • 派生类的指针不允许指向它基类的对象。

  • 基类的指针指向它的公有派生类的对象时,只能用它来直接访问派生类中从基类继承来的成员,而不能直接访问公有派生类中定义的新成员。

  • 动态联编提高了编程的灵活性和程序的易维护性,但与静态联编相比,函数调用速度慢。

五、共勉:

????????以上就是我对C++多态性——(2)联编的理解,希望本篇文章对你有所帮助,也希望可以支持支持博主,后续博主也会定期更新学习记录,记录学习过程中的点点滴滴。如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++多态性的理解,请持续关注我哦!!!?

文章来源:https://blog.csdn.net/2301_80585598/article/details/135350431
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。