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

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

动态内存和类

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运算符创建的对象时不会自动调用析构函数。因此需要用对象显示的调用析构函数。

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



目录
相关文章
|
4月前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
55 0
|
8天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
27 4
|
9天前
|
存储 Java 程序员
结构体和类的内存管理方式在不同编程语言中的表现有何异同?
不同编程语言中结构体和类的内存管理方式既有相似之处,又有各自的特点。了解这些异同点有助于开发者在不同的编程语言中更有效地使用结构体和类来进行编程,合理地管理内存,提高程序的性能和可靠性。
17 3
|
11天前
|
存储 缓存 Java
结构体和类在内存管理方面的差异对程序性能有何影响?
【10月更文挑战第30天】结构体和类在内存管理方面的差异对程序性能有着重要的影响。在实际编程中,需要根据具体的应用场景和性能要求,合理地选择使用结构体或类,以优化程序的性能和内存使用效率。
|
11天前
|
存储 缓存 算法
结构体和类在内存管理方面有哪些具体差异?
【10月更文挑战第30天】结构体和类在内存管理方面的差异决定了它们在不同的应用场景下各有优劣。在实际编程中,需要根据具体的需求和性能要求来合理选择使用结构体还是类。
|
5月前
|
消息中间件 存储 测试技术
【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据
【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据
|
1月前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(二)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
1月前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(三)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
1月前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(一)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
6月前
|
存储 C++
webserver--Buffer类实现内存缓冲区读写(全代码)
webserver--Buffer类实现内存缓冲区读写(全代码)