您现在的位置是:亿华云 > 数据库
EasyC++,继承和动态内存分配
亿华云2025-10-09 01:21:39【数据库】8人已围观
简介继承和动态内存分配今天这篇文章来聊聊继承与动态内存分配。这里面有一个问题,当我们的基类使用动态内存分配,并且重新定义赋值和复制构造函数,这会对派生类的实现有什么影响呢?我们来看两种情况。派生类不用ne
继承和动态内存分配
今天这篇文章来聊聊继承与动态内存分配。承和
这里面有一个问题,动态当我们的内存基类使用动态内存分配,并且重新定义赋值和复制构造函数,分配这会对派生类的承和实现有什么影响呢?
我们来看两种情况。
派生类不用new
假设基类中使用了动态内存分配:
class baseDMA { private: char *label; int rating; public: baseDMA(const char* l="null",动态 int r=0); baseDMA(const baseDMA& rs); virtual ~baseDMA(); baseDMA &operator=(const baseDMA& rs); };在这个声明里包含了构造函数、析构函数、内存复制构造函数和重载赋值运算符。分配
现在假设我们从baseDMA派生出了类lackDMA,承和但是动态后者不使用new:
class lackDMA: public baseMDA { private: char color[40]; public: ... };问题来了,我们要不要给lackDMA这个类定义析构函数、内存复制构造函数和赋值运算符呢?分配
答案是不需要。
首先是承和析构函数,这个很好想明白,动态如果我们没有定义析构函数,内存那么编译器会自动定义一个不执行任何操作的默认析构函数。实际上派生类的析构函数往往会在执行一些逻辑之后调用基类的构造函数,因为lackDMA类中的成员不是通过new创建的,因此不需要额外的操作,所以默认析构函数是合适的。源码下载
同样的默认复制构造函数也会执行非new创建成员的复制,所以对于color变量来说是没问题的。并且在派生类当中,默认复制构造函数除了会复制非new创建的成员之外,还会调用基类的复制构造函数来复制父类成员的部分。所以,对于派生类lackDMA来说,我们使用默认的复制构造函数一样没有问题。
赋值也是一样的,默认的赋值运算符也会自动使用基类的赋值运算符来对基类的成员进行赋值。
派生类使用new
我们再来看看派生类当中使用了new的情况。
class hasDMA: public baseMDA { private: char *style; public: ... };在hasDMA这个类当中,我们添加了一个需要使用new创建的char*成员。在这种情况下,我们就没办法使用默认的函数了,就必须定义显式析构函数、复制构造函数和赋值运算符了,b2b信息网我们一个一个来看。
首先是析构函数,派生类的析构函数会自动调用基类的析构函数,所以我们只需要在析构函数当中释放派生类中独有的成员变量即可。
hasDMA::~hasDMA() { delete []style; }然后我们再来看看拷贝构造函数,由于派生类不能访问基类private成员,所以我们需要调用基类的拷贝构造函数。
hasDMA::hasDMA(const hasDMA& hs): baseDMA(hs) { style = new char[std::strlen(hs.style) + 1]; std::strcpy(style, hs.style); }最后是赋值运算符,同样,由于派生类不能访问基类中私有成员,我们也需要借助基类的赋值运算符:
hasDMA &hasDMA::operator(const hasDMA& hs) { if (this == &hs) return *this; baseDMA::operator=(hs); delete []style; style = new char[std::strlen(hs.style) + 1]; std::strcpy(style, hs.style); return *this; }这当中有一个语句看起来有些奇怪:
baseDMA::operator=(hs);这是我们手动显式调用了基类的赋值运算符,我们直接用等于号赋值也有同样的效果:
*this = hs;为什么不这么干呢?这是因为编译器在执行的时候会默认调用子类的赋值运算符hasDMA::operator=,从而导致一直递归导致死循环。
所以我们需要手动写明作用域解析符,表明这是调用的父类赋值运算符,而非派生类的运算符,这一点比较隐晦,高防服务器要千万注意。
很赞哦!(4)
相关文章
- 4、域名传输时,取决于域名原始用户的邮箱是否有效,以及他是否将密码发送到此邮箱。
- 巧用ActionFilterAttribute实现API日志的记录
- LeetCode题解之两个有序链表合并
- JDK15类的后半生:准备、解析、初始化、卸载过程详解
- 因为域名解析需要同步到DNS根服务器,而DNS根服务器会不定时刷,只有DNS根服务器刷新后域名才能正常访问,新增解析一般会在10分钟左右生效,最长不会超过24小时,修改解析时间会稍微延长。
- 掌握6大模块、7个核心概念!帮你搞定Mycat中间件
- 拼图也能写代码?快来试试这个谷歌开源的工具!
- 巧用Dictionary实现日志数据批量插入
- CNAME:对应解析的记录值为域名地址
- 基于Python的Stacking集成机器学习实践