类和动态内存分配

本文的主要内容:
1、类成员动态分配内存一系列操作方法(分配、释放)
2、特殊成员函数:复制构造函数、赋值运算符重载函数
3、静态类成员、静态成员函数
4、动态分配对象存储空间(常规new 和定位new)
5、指向对象的指针

了解一下对象创建过程:
1、根据类声明分配合适的存储空间,这里对象只存储非静态的数据成员,静态数据成员存在特殊的位置被所有对象共享。
2、调用构造函数,为对象的数据成员赋初值
3、对象的生命周期结束时自动调用析构函数(对于用定位new分配的匿名对象不会自动调用析构函数,程序猿要自己添加调用析构函数的代码)

一个很常见的问题:
编译时根据数据的类型便可以分配所需存储空间大小,由类型限制了存储空间太死板了。(之前复习过,为了灵活使用内存空间(匿名的存储空间),我们可以利用new在运行时才确定数据的存储大小)。
如何确定类对象所需的内存空间?取决于数据成员类型
类是数据和方法的封装,通俗说,将类看成一个黑盒子即不同数据类型的组合,编译时创建类对象就是根据数据成员类型来确定对象所需的空间。
解决方法:
希望类的成员所需的内存空间是在运行分配的,但是类对象的存储大小必须是确定的(各个成员类型必须是确定的),指针可以帮助我们解决这个问题!指针所需的内存空间是确定的,这样一来类所需空间大小是确定的,等到程序运行时,利用new在堆中分配合适的内存大小,并将这个地址值赋给对象的指针即可(利用构造函数实现:在构造函数内分配空间、将其地址值赋值给指针变量**,因而通过该指针,关联了一个大小可变的内存空间**,便可以视为类中存储了可变类型的数据)。对象存储时地址,通过该地址找到堆内实际数据。
对象的生命周期结束时,将自动调用析构函数,释放对象所占用的内存空间,但是数据成员关联的匿名存储空间并不会被释放,但其实匿名空间的值也是改对象的一部分,因而不显示使用delete释放该片空间,可以说没有完整的释放对象空间。delete将释放构造函数中new所分配的空间。
讲完了,如何为对象分配内存空间。回顾一下,构造函数(创建对象时总会被调用到)用途:初始化数据成员。因而,对于想存储大小可变空间,需在构造函数内完成一系列工作:动态分配内存、将实参的值拷贝到动态空间中、将指针指向初始化后的内存空间。
无论是什么类型最底层的表示都是基本类型的复合!String类为了能灵活分配内存空间,数据成员必须是char *(字符串不就是多个字符,最底层的存储类型就是char)

string类(动态分配空间存字符串)实现:
通过C风格字符串(根据字符串地址)创建String对象,c风格字符串三种形式:“***”、 char、char[],但终归是字符串地址。

特殊的成员函数(编译器为我们自动生成的):
1、默认构造函数(编译器使得在创建对象的时候总会调用构造函数):编译器生成的默认构造函数无参数,什么都不做
2、默认析构函数
3、复制构造函数
4、赋值运算符重载函数
5、地址运算符

复制构造函数:用已知对象创建并初始化一个新的对象。
原型:
在这里插入图片描述

何时被调用?
创建新的对象并初始化为同类现有对象;产生了现有对象的副本时(参数的对象传递、返回对象);
复制构造函数做些什么?
浅复制:逐个复制对象的成员值(除静态成员变量),如果成员本身就是个对象,则调用该成员的复制构造函数

在这里插入图片描述
由于是浅复制,成员是指针时将产生错误,只是复制指针值到新的对象成员,两个对象的数据成员指向同一片内存空间,一旦有一个对象被释放,其关联的内存空间也被释放,那么另一个对象的指针将悬空,所指空间的数据已经被破坏了。
为了解决浅复制的问题,可在类中定义复制构造函数完成深度复制产生新的存储空间,这样一来编译器就不会再我们的程序生成默认的复制构造函数。
当我们的数据成员中包含了使用new的指针,我们一定要自定义复制构造函数完成深度复制。(一旦一个对象被释放,其对应的内存空间也会被释放,浅复制将带来悬空指针)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值