[C++]关于多态的一道题目

本文详细解析了C++中的多态性概念,包括编译时多态与运行时多态的区别,以及如何通过虚函数实现多态。通过具体代码示例展示了不同类型的指针在调用虚函数和非虚函数时的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先介绍一下多态的概念:

C++支持两种多态性,分别是编译时和运行时。在编译时就确定的函数调用称为静态联编,它通过使用函数重载,模板等实现的。在运行时才确定的函数调用称为动态联编,它通过虚函数来实现的。虚函数的声明方式是在函数原型上加关键字virtual,在基类中含义虚函数,在派生类中的函数不需要显示地写出virtual关键字。

多态的一般使用方法:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数的时候,将总被限制za9基类函数本身,而无法调用到子类中被重写过的函数。

#include<iostream>  
using namespace std;

class A
{
public:
	void foo()
	{
		printf("1\n");
	}
	virtual void fun()
	{
		printf("2\n");
	}
};
class B : public A
{
public:
	void foo()
	{
		printf("3\n");
	}
	void fun()
	{
		printf("4\n");
	}
};
int main(void)
{
	A a;
	B b;
	A *p = &a;
	p->foo();//1
	p->fun();//2
	p = &b;
	p->foo();//1
	p->fun();//4
	cout << "********" << endl;
	B *ptr = (B*)&a;
	ptr->foo();//3
	ptr->fun();//2
	return 0;
}


第一个p->foo()和p->fuu()都很好理解,本身是基类指针,指向的又是基类对象,调用的都是基类本身的函数,因此

输出结果就是1、2。第二个输出结果就是1、4。p->foo()和p->fuu()则是基类指针指向子类对象,正式体现多态的用法,

p->foo()由于指针是个基类指针,指向是一个固定偏移量的函数,因此此时指向的就只能是基类的foo()函数的代码了,

因此输出的结果还是1。而p->fun()指针是基类指针,指向的fun是一个虚函数,由于每个虚函数都有一个虚函数列表,

此时p调用fun()并不是直接调用函数,而是通过虚函数列表找到相应的函数的地址,因此根据指向的对象不同,函数地址

也将不同,这里将找到对应的子类的fun()函数的地址,因此输出的结果也会是子类的结果4。

笔试的题目中还有一个另类测试方法。即
       B *ptr = (B *)&a;  ptr->foo();  ptr->fun();
  问这两调用的输出结果。这是一个用子类的指针去指向一个强制转换为子类地址的基类对象。
这两句调用的输出结果

是3,2.

利用下面的规则可以很方便地得出上面的结果:
主要涉及到两类多态的问题,一个是编译时多态,一个是运行时多态,non-virtual函数是执行的编译时多态,virtual是运行

时多态。 对non-virtual成员函数的调用由指针/引用的类型决定,而virtual 成员函数则有赋值类型决定。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值