第十二章-类和动态内存分配

简介: 第十二章-类和动态内存分配

动态内存和类

1.静态数据成员在类声明中声明,在包含类方法的文件中初始化。初始化时使用作用域运算符来指出静态成员所属的类。但是如果静态成员是整型或者是枚举型const,则可以在类声明中初始化。

.2.C++会自动提供这些函数,如果类中没有定义这些函数的时候。

默认构造函数

默认析构函数

复制构造函数

赋值运算符

地址运算符

3.复制构造函数:用于将一个对象复制到新创建的对象中

何时调用复制构造函数:(1)新建对象并将其初始化为同类现有对象时,复制构造函数将被调用。(2)每当程序生成了对象副本时,编译器都将使用复制构造函数。(注意一点,初始化=定义+赋值,而先定义再赋值不会调用赋值构造函数)

4.默认复制构造函数提供的是浅拷贝,个人理解是不创建新的空间,直接将已存在空间的地址复制给新的对象,这样旧的对象和新的对象都指向同一个内存。

5.静态成员变量为这种类的所以对象共有。

6.如果类中包含这样的静态数据成员,即其值将在新对象被创建时发生变化,则应该提供一个对计数进行更新的显示复制构造函数。

7.不应该将同一个内存释放两次,这样就会造成不确定的危险。

8.如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这种复制被称为深度复制。

9.赋值运算符也存在相同的浅拷贝问题,同理应该使用深拷贝去克服它。注意一点是,需要先判断是都是自己赋值给自己,如果是的话直接返回*this,如果不是则先删除以前在内存中存在的数据。如果不删除,在创建新的内存的时候,指向以前内存的指针就不存在了,就会造成内存泄漏的问题。如果返回的是对象的引用则可以连续操作。

10.当const在函数名前面的时候修饰的是函数返回值。

当const在函数名后面表示是常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。该类的this指针为const类型,不能改变类的成员变量的值。

11.静态成员函数在函数原型前面加static。注意:不能使用对象调用静态成员函数,如果静态成员函数是在共有部分声明的话,则可以使用类名和作用域解析运算符来调用它。静态成员函数只能调用静态成员变量。


有关返回对象的说明

1.返回指向const对象的引用

返回对象将调用复制构造函数,而返回引用不会

引用指向的对象应该在调用函数执行时存在

v1与v2被声明为const引用,因此返回必须为const

2.返回非const对象的引用:常用于重载赋值运算符以及重载与cout一起使用的<<运算符。

对于cout与<<一起使用的重载版本来说,必须返回ostream的引用,因为载cout对象中并没有公有的复制构造运算符。

3.返回对象

如果返回的对象是被调用函数中的局部变量,则不应按引用方式返回,因为在函数执行完之后,局部对象将调用析构函数,删除对象。返回引用就没办法指向正确的内存。

4.返回const对象

返回对象是可做为左值的,所有可能会犯 将返回值做为左值的情况。如果返回const对象,就可以避免这种错误。


调用析构函数的三种情况

1.如果对象是动态变量,则当执行完定义该对象的程序块时,将调用该对象的析构函数。

2.如果对象是静态变量,则在程序结束时调用对象的析构函数。

3.如果对象是用new创建的,则需要显示使用delete删除对象时,其析构函数才会被调用。


定位new运算符和new运算符在删除对象时的差别

存在两个问题;

1.在创建第二个对象的时候,定位new运算符使用一个新对象来覆盖第一个对象的内存单元,所有需要提供两个位于缓冲区的不同地址。

2.在用delete[]删除定位new运算符创建的对象时不会自动调用析构函数。因此需要用对象显示的调用析构函数。

注意:删除顺序,是先创建的后删除进行删除,因为晚创建的可能依赖于早早创建的对象。另外仅当所有对象都被销毁后,才能释放用于存储这些对象的缓冲区。



目录
相关文章
|
6月前
|
存储 C++
C++:类的内存布局
C++:类的内存布局
|
4月前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
52 0
|
5月前
|
消息中间件 存储 测试技术
【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据
【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据
|
27天前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(二)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
27天前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(三)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
27天前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(一)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
6月前
|
存储 C++
webserver--Buffer类实现内存缓冲区读写(全代码)
webserver--Buffer类实现内存缓冲区读写(全代码)
|
3月前
|
存储 程序员 Python
Python类的定义_类和对象的关系_对象的内存模型
通过类的定义来创建对象,我们可以应用面向对象编程(OOP)的原则,例如封装、继承和多态,这些原则帮助程序员构建可复用的代码和模块化的系统。Python语言支持这样的OOP特性,使其成为强大而灵活的编程语言,适用于各种软件开发项目。
31 1
|
3月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
3月前
|
缓存 程序员
封装一个给 .NET Framework 用的内存缓存帮助类
封装一个给 .NET Framework 用的内存缓存帮助类