【c++】多态

多态(Polymorphism)是面向对象编程(OOP)中的一个重要概念,指的是同一个接口或方法在不同情况下表现出不同的行为。多态性允许不同的类对同一消息做出不同的响应,增强了代码的灵活性和可扩展性。多态分为运行时多态(动态多态)和,编译时多态(静态多态),在这里我们主要介绍运行时多态。

编译时多态(静态多态)

编译时多态就是我们前边讲的函数重载和函数模板,传不同的参数就会调用不同的函数,通过参数不同来达到多种形态。函数重载和函数模板在编译时就已经确定要调用的函数,所以称为编译时多态(静态多态),实参传给形参的参数匹配是在编译时完成的。

运行时多态(动态多态)

不同于编译时多态,运行时多态在编译时还没有确认要调用函数,在要调用一个函数时,不同的对象去调用,完成的行为是不一样的。例如,同样一个叫声的函数,用Dog(狗)类型实例化出的对象调出来的是 '汪汪'。用Cat(猫)类实例化出的对象去调出来的则是'喵喵'。

运行时多态通过不同类型的对象去调用实现多种形态,编译时多态通过参数匹配来实现多种形态。

多态的定义和实现

多态是继承关系下的类对象,去调用同一函数,产生不同的行为。

实现多态的两个必须条件
• 必须是基类的指针或者引⽤调⽤虚函数
• 被调⽤的函数必须是虚函数,并且完成了虚函数重写/覆盖。

代码语言:javascript

AI代码解释

复制代码
class Person
{
public:
	virtual void buyticket()
	{
		cout << "全价买票" << endl;
	}
private:
};

class Student :public Person
{
public:
	virtual void buyticket()
	{
		cout << "七五折买票" << endl;
	}
};
void func(Person& a)
{
	a.buyticket();
}
int main()
{
	Person a;
	Student b;
	func(a);
	func(b);
	return 0;
}

如果func()中参数类型为Student:

代码语言:javascript

AI代码解释

复制代码
class Person
{
public:
	virtual void buyticket()
	{
		cout << "全价买票" << endl;
	}
private:
};

class Student :public Person
{
public:
	virtual void buyticket()
	{
		cout << "七五折买票" << endl;
	}
};
void func(Student& a)
{
	a.buyticket();
}
int main()
{
	Person a;
	Student b;
	func(a);
	func(b);
	return 0;
}

如果buyticket()不是虚函数:

代码语言:javascript

AI代码解释

复制代码
class Person
{
public:
	void buyticket()
	{
		cout << "全价买票" << endl;
	}
private:
};

class Student :public Person
{
public:
	virtual void buyticket()
	{
		cout << "七五折买票" << endl;
	}
};
void func(Person& a)
{
	a.buyticket();
}
int main()
{
	Person a;
	Student b;
	func(a);
	func(b);
	return 0;
}

虚函数

类成员函数前⾯加virtual修饰,那么这个成员函数被称为虚函数。注意⾮成员函数不能加virtual修

饰。

代码语言:javascript

AI代码解释

复制代码
class Person
{
public:
	void buyticket()
	{
		cout << "全价买票" << endl;
	}

};
虚函数的重写/覆盖

虚函数的重写(Override)是面向对象编程中的一个重要概念,主要用于实现多态性。当一个派生类继承自基类时,派生类可以重写基类中的虚函数,以提供自己的实现。这样,当通过基类指针或引用调用该函数时,实际执行的是派生类中的版本。

注意:派生类的虚函数前面可以不加virtual关键字,一个函数在基类中被声明为virtual,在派生类中自动成为虚函数。但是这样牺牲了代码的可读性,尽量加上。

代码语言:javascript

AI代码解释

复制代码
class Person
{
public:

	virtual void buyticket()
	{
		cout << "全价买票" << endl;
	}
};

class Student:public Person
{
public:
	void buyticket()//不加virtual也是虚函数
	{
		cout << "半价买票" << endl;
	}
};



void func(Person* ptr)
{
	ptr->buyticket();
}

int main()
{
	Person a;
	Student b;
	a.buyticket();
	b.buyticket();

	return 0;
}

观察下面一段代码:

代码语言:javascript

AI代码解释

复制代码
class A
{
public:
	virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
	virtual void test() { func(); }
};
class B : public A
{
public:
	void func(int val = 0) { std::cout << "B->" << val << std::endl; }
};
int main(int argc, char* argv[])
{
	B* p = new B;
	p->test();
	return 0;
}

这段程序的输出结果是什么呢?

p是指向B类型的指针,指向谁,谁调用,所以是调用B类型中的func()函数,但是这里要注意一点:默认参数的值是根据调用者的静态类型(编译时)决定的,而不是动态类型(运行时)

相关推荐
weixin199701080167 分钟前
《淘宝TOP API:落地方案、接口边界与业务踩坑 —— 聚石塔内外价差 10 倍的真相》(附 Python 源码)
开发语言·python
前端 贾公子8 分钟前
LangGraph == 图的状态(State)管理 (上)
java·开发语言·数据库
huaweichenai15 分钟前
spring boot 实现file文件上传
java·spring boot·后端
汉克老师31 分钟前
CSP-S 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-s·小学生·学c++编程
VX_bysjlw98534 分钟前
数码设备销售网站设计与实现39138-计算机毕设原创(免费领源码+带部署教程)
java·vue.js·spring boot·mysql·tomcat·mybatis·idea
_wyt00137 分钟前
洛谷 P10112 [GESP202312 八级] 奖品分配 题解
c++·数学·gesp·八级
荣码1 小时前
从0到1搭一个生产级RAG系统:串联前面21篇所有知识
java·python
xuxigifxfh1 小时前
牛客:HJ170 01序列
java·开发语言·算法·华为机考
朝朝辞暮i1 小时前
C++ 第 33 课:事件循环——spin() 到底在干什么
开发语言·c++·算法
野生技术架构师1 小时前
牛客网互联网大厂 Java 高频面试题整理(持续更新)
java·开发语言