c++ 静态联编+动态联编 (多态)

2023-12-29 20:26:36

静态多态 +动态多态

1)静态多态动态多态的区别就是函数地址早绑定(静态联编)还是晚绑定(动态联编)。

如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态),就是说地址是早绑定的。

而如果函数的调用地址不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)。

2)运算符重载函数重载就是编译时多态,而派生类虚函数实现运行时多态

动态多态产生条件

1)先有继承关系

2)父类中有虚函数,子类重写父类虚函数

返回值,函数名字,函数参数,必须和父类完全一致(析构函数除外)
子类中virtual关键字可写可不写,建议写

3)父类的指针或引用指向子类对象

对于有父子关系的两个类,指针或者引用是可以转换的。

动态多态 +虚函数 原理

原理

在这里插入图片描述

通过指针偏移调用虚函数

在这里插入图片描述

多态中的 类型转换

向上类型转换 +向下类型转换

在这里插入图片描述

重载 重定义 重写 (区分)

重载

同一作用域的同名函数

  1. 同一个作用域
  2. 参数个数,参数顺序,参数类型不同
  3. 和函数返回值,没有关系
  4. const 也可以作为重载条件 //do(const Teacher& t){} do(Teacher& t)
重定义

隐藏基类函数

  1. 有继承
  2. 子类(派生类)重新定义父类(基类)的同名成员(非virtual函数)
重写

覆盖基类虚函数

  1. 有继承
  2. 子类(派生类)重写父类(基类)的 virtual 函数
  3. 函数返回值,函数名字,函数参数,必须和基类中的虚函数一致

案列

利用多态实现计算器(案列)

常规思路

这种程序不利于扩展,维护困难,如果修改功能或者扩展功能需要在源代码基础上修改

面向对象程序设计一个基本原则:开闭原则(对修改关闭,对扩展开放)

//计算器
class Caculator{
public:
	void setA(int a){
		this->mA = a;
	}
	void setB(int b){
		this->mB = b;
	}
	void setOperator(string oper){
		this->mOperator = oper;
	}
	int getResult(){
		
		if (this->mOperator == "+"){
			return mA + mB;
		}
		else if (this->mOperator == "-"){
			return mA - mB;
		}
		else if (this->mOperator == "*"){
			return mA * mB;
		}
		else if (this->mOperator == "/"){
			return mA / mB;
		}
	}
private:
	int mA;
	int mB;
	string mOperator;
};


利用多态实现
//抽象基类
class AbstractCaculator{
public:
	void setA(int a){
		this->mA = a;
	}
	virtual void setB(int b){
		this->mB = b;
	}
	virtual int getResult() = 0;
protected:
	int mA;
	int mB;
	string mOperator;
};

//加法计算器
class PlusCaculator : public AbstractCaculator{
public:
	virtual int getResult(){
		return mA + mB;
	}
};

//减法计算器
class MinusCaculator : public AbstractCaculator{
public:
	virtual int getResult(){
		return mA - mB;
	}
};

//乘法计算器
class MultipliesCaculator : public AbstractCaculator{
public:
	virtual int getResult(){
		return mA * mB;
	}
};

void DoBussiness(AbstractCaculator* caculator){
	int a = 10;
	int b = 20;
	caculator->setA(a);
	caculator->setB(b);
	cout << "计算结果:" << caculator->getResult() << endl;
	delete caculator;
}

多态性改善了代码的可读性和组织性,同时也使创建的程序具有可扩展性,项目不仅在最初创建时期可以扩展,而且当项目在需要有新的功能时也能扩展。

重载 重定义 重写 (案列)

class A{
public:
	//同一作用域下,func1函数重载
	void func1(){}
	void func1(int a){}
	void func1(int a,int b){}
	void func2(){}
	virtual void func3(){}
};

class B : public A{
public:
	//重定义基类的func2,隐藏了基类的func2方法
	void func2(){}
	//重写基类的func3函数,也可以覆盖基类func3
	virtual void func3(){}
};

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