类的多态(Num020)

目录

一、静态联编和动态联编:

什么是联编:

静态联编和动态联编:

代码示例:

实现动态联编的条件:

二、多态:

虚函数的特点:

虚函数的使用:

代码示例:

三、抽象类:

代码示例:

头文件:

同名.cpp文件:

四、final:


一、静态联编和动态联编:

什么是联编:

  • 联编,指的是++计算机自身彼此关联的过程,在这个过程中确定程序中的操作调用与之前操作的代码段之间的映射关系++

  • 比如:函数重载时,编译器会根据函数名和函数的参数来区别要执行的函数(哪一段代码)。这就是建立的一种映射关系,明确函数调用时会执行哪一个代码段

静态联编和动态联编:

1、静态联编:

指的是联编工作出现在写代码的阶段,++又称之为早期联编,或静态约束++

2、动态联编:

指的是编译阶段不能确定将要调用的函数,只能在程序运行的时候才能确定将要调用的函数,也就是说在程序运行的时候才将函数实现和函数调用关联。也叫**++晚期联编,或动态约束++**

代码示例:

cpp 复制代码
#include<iostream>

using namespace std;
//静态联编
void fun() {
	cout << "这是一个函数" << endl;
}

void fun(int x) {
	cout << "这也是一个函数" << endl;
}

int main() {
	fun();
		
	return 0;
}

实现动态联编的条件:

  1. 必须把动态联编的行为定义为类的虚函数

  2. 必须有类,而且类之间满足父子关系,这个行为通常是重写的父类的虚函数

  3. 必须是先使用基类指针或引用指向派生类对象,然后使用基类指针调用虚函数成员其实动态联编就是多态

二、多态:

  • 具有多种形式或者状态

  • 同一个接口,通过不同的对象调用就有不同的效果

多态的实现需要虚函数:

在类中的函数成员前面加一个virtual关键字即可

虚函数的特点:

  1. 如果在类中定义的虚函数,那么系统会为这个类维护一个虚函数表

  2. 类中会多出4个字节的指针去指向这个虚函数表,在虚函数表中保存了虚函数的首地址,在调用虚函数的时候就会先到表中查找虚函数,然后调用,就比普通函数多了1步操作

  3. 虚函数表不会被继承,但是表中的项会被继承(虚函数会被继承)

虚函数的使用:

  1. 父类中的虚函数++子类通常都会继承重写为自己的功能++

  2. 通过父类指针或引用调用的这个虚函数成员,++父类指针或引用指向哪一个子对象就是调用哪一个子对象的虚函数成员++

  3. 如果++子对象是new出来的,那么delete父类指针不会调用子类的析构函数,把父类的析构函数定义为虚析构,那么就会调用子类的析构++

代码示例:

cpp 复制代码
#include<iostream>

using namespace std;

class animal {
public:
	virtual void speak() {
		cout << "这是一个动物会叫" << endl;
	}
	animal() {
		cout << "animal类构造" << endl;
	}
	virtual ~animal() {
		cout << "animal类死亡" << endl;
	}
};

class cat :public animal {
public:
	virtual void speak() {
		cout << "这是一只猫,会喵喵喵" << endl;
	}
};

class dog :public animal {
public:
	virtual void speak() {
		cout << "这是一只狗,会汪汪汪" << endl;
	}
	dog() {
		cout << "dog类构造" << endl;
	}
	~dog() {
		cout << "dog类死亡" << endl;
	}
};

void zoo(animal* a1) {
	a1->speak();
}

int main() {
	//animal a1;
	//cat c1;
	animal* d1=new dog;
	zoo(d1);
	delete d1;
	return 0;
}

三、抽象类:

  1. 抽象类++也是一个类,只不过不能拿来定义对象++

  2. 抽象类是++用来描述一些公有的属性和行为的++

  3. 一个类中++拥有一个纯虚函数,这个类就变为了抽象类++

  4. 子类如果++继承了抽象类,那么子类必须重写抽象类中的所有纯虚函数++ (构造析构除外),++否则子类也会变为抽象类++

  5. 纯虚函数的定义:++virtual void fun()=0;不需要实现++

代码示例:

头文件:

cpp 复制代码
#pragma once
#include<iostream>

using namespace std;
class CHero
{
public:
	virtual void atk() = 0;
};

class hero1 :public CHero {
public:
	void atk() {
		cout << "发射光线" << endl;
	}
};

class hero2 :public CHero {
public:
	void atk() {
		cout << "飞踢" << endl;
	}
};

class hero3 :public CHero {
public:
	void atk() {
		cout << "肘击" << endl;
	}
};

class bas {
public:
	virtual void atk() = 0;
};

class bas1 :public bas {
public:
	void atk() {
		cout << "怪兽1" << endl;
	}
};

class bas2 :public bas {
public:
	void atk() {
		cout << "怪兽2" << endl;
	}
};

class bas3 :public bas {
public:
	void atk() {
		cout << "怪兽3" << endl;
	}
};

void atk1(CHero& h1, bas& b1) {
	h1.atk();
	b1.atk();
}

同名.cpp文件:

cpp 复制代码
#include "CHero.h"

int main() {
	hero1 h1;
	hero2 h2;
	hero3 h3;

	bas1 b1;
	bas2 b2;
	bas3 b3;

	atk1(h3, b2);
}

四、final:

  1. 在虚函数的后面加修饰

  2. 在定义类的后面加修饰

相关推荐
码匠许师傅3 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
2603_965148113 小时前
如何解析JSON数据?API返回的商品信息处理教程
开发语言·数据库·python·自动化·json·api
小小龙学IT4 小时前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
知无不研5 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_29146 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
C++ 老炮儿的技术栈7 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011167 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据7 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
zlinear数据采集卡8 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Poo_Chai8 小时前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库