继承和动态内存分配

36 篇文章 1 订阅

1、派生类不使用new:

此时不需要为派生类定义显式析构函数、复制构造函数和赋值运算符。

2、派生类使用new:

此时需要为派生类定义显式析构函数、复制构造函数和赋值运算符。
基类中使用了动态内存分配:

class baseDMA
{
private:
	char * label;
	int rating;
public:
	baseDMA(const char * l="null", int r=-);
	baseDMA(const baseDMA & rs);
	virtual ~baseDMA();
	baseDMA & operator=(const baseDMA & rs);
	friend ostream & operator<<(ostream &os, const baseDMA &rs);
...
};

派生类也使用了new:

class hasDMA: public baseDMA
{
private:
	char * style;
public:
...
};		

1. 析构函数
派生类析构函数自动调用基类析构函数,故其自身的职责是对派生类构造函数执行工作的进行清理。因此,hasDMA析构函数必须释放指针style管理的内存,并依赖于baseDMA的析构函数来释放指针label管理的内存。

baseDMA::~baseDMA()
{
	delete [] label;
}
hasDMA::~hasDMA()
{
	delete [] sytle;
}

2. 复制构造函数
hasDMA复制构造函数只能访问hasDMA的数据,因此它必须调用baseDMA复制构造函数(通过成员初始化列表语法)来处理共享的baseDMA数据。

hasDMA::hasDMA(const hasDMA & hs) : baseDMA(hs)
{
	style = new char[strlen(hs.style)+1];
	strcpy(style,hs.style);
}

这里,成员初始化列表将一个hasDMA引用传递给baseDMA构造函数,基类引用可以指向派生类对象,实现了向上强制类型转换。1

3. 赋值运算符
hasDMA方法只能直接访问hasDMA的数据,它又不是构造函数,不能使用成员初始化列表语法,只能通过作用域解析运算符显式调用基类赋值运算符。

hasDMA & hasDMA::operator=(const hasDMA & hs)
{
	if(this == &hs)
		return *this;
	baseDMA::operator=(hs);	//作用域解析运算符显式调用基类赋值运算符
	delete [] style;
	style = new char[strlen(hs.style)+1];
	strcpy(style,hs.style);
	return *this;
}

4. 友元函数
作为hasDMA类的友元,该函数可以访问style成员,但它不是baseDMA类的友元,要使用baseDMA类的友元函数operator<<()。但友元不是成员函数,不能使用作用域解析运算符,必须使用强制类型转换

ostream & operator<<(ostream & os, const hasDMA & hs)
{
	os <<const baseDMA &)hs;	//将参数const hasDMA&转换成const baseDMA&类型
	os<<"Style: " << hs.style <<endl;
	return os;
}

  1. 详见 派生类和基类↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值