Item3 不要对数组使用多态

本文探讨了C++中类继承与多态性的概念,特别是如何通过基类指针或引用来操作派生类对象,并展示了不当使用多态可能带来的问题。通过具体的代码示例,说明了当尝试将派生类数组传递给期望基类数组的函数时可能出现的错误。

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

类继承的最重要的特性是你可以通过基类指针或引用来操作派生类。这样的指针或引用具有行为的多态性,就好像它们同时具有多种形态。C++允许你通过基类指针和引用来操作派生类数组。不过这根本就不是一个特性,因为这样的代码几乎从不如你所愿地那样运行。

现在我们定义一个基类和派生类:sizeof(CBase) = 4,sizeof(CDerived) = 8;

class CBase{
public:
    int x;
public:
    CBase(int a) : x(a){}
};
class CDerived : public CBase{
public:
    int y;
public:
    CDerived(int a, int b) : CBase(a), y(b){}
};

一个打印基类对象数据的函数:

void DispBaseArr(const CBase arrObj[], int iCnt)
{
    for(int i = 0; i < iCnt; i++){
        cout << arrObj[i].x << endl;
    }
}

当我们传入符合要求的参数【基类对象数组】,输出就能达到我们预期的效果:1,2,3,4,5

CBase arrBase[5] = {1, 2, 3, 4, 5};
DispBaseArr(arrBase, sizeof(arrBase)/sizeof(CBase));

当我们传入不符合要求的参数【派生对象的数组】,输出的序列将会是这样的:1,10,2,20,3

CDerived arrDerived[5] = {CDerived(1,10), CDerived(2,20), CDerived(3,30), CDerived(4,40), CDerived(5,50)};
DispBaseArr(arrDerived, sizeof(arrDerived)/sizeof(CDerived));

如果你把一个含有 CDerived 对象的数组变量传递给 DispBaseArr函数,你的编译器就会犯错误。在这种情况下,编译器原先已经假设数组中元素与 CBase 对象的大小一致,但是现在数组中每一个对象大小却与 CDerived 一致。派生类的长度通常都比基类要长。我们料想 CDerived 对象长度的比 CBase长。如果如此的话,DispBaseArr函数生成的指针算法将是错误的, 没有人知道如果用 CDerived 数组来执行 DispBaseArr函数将会发生什么样的后果。不论是什么后果都是令人不愉快的。

完整示例代码如下:

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;

//不要对数组使用多态
class CBase{
public:
	int x;
public:
	CBase(int a) : x(a){}
};
class CDerived : public CBase{
public:
	int y;
public:
	CDerived(int a, int b) : CBase(a), y(b){}
};

void DispBaseArr(const CBase arrObj[], int iCnt)
{
	for(int i = 0; i < iCnt; i++){
		cout << arrObj[i].x << endl;
	}
}
void main()
{
	CBase arrBase[5] = {1, 2, 3, 4, 5};
	DispBaseArr(arrBase, sizeof(arrBase)/sizeof(CBase));
	CDerived arrDerived[5] = {CDerived(1,10), CDerived(2,20), CDerived(3,30), CDerived(4,40), CDerived(5,50)};
	DispBaseArr(arrDerived, sizeof(arrDerived)/sizeof(CDerived));
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值