【C++】动态对象创建

您所在的位置:网站首页 动态构造数组 【C++】动态对象创建

【C++】动态对象创建

2023-08-16 14:20| 来源: 网络整理| 查看: 265

在C语言中提供了内存分配函数malloc()(或calloc()/realloc())和free(),这些函数在运行时从堆内存中分配存储单元。

然而,在C++中这些函数将不能很好地运行。因为构造函数不允许我们向它传递内存地址来进行初始化。

C++是如何保证正确的初始化和清理,又允许我们在堆上动态创建对象呢?

malloc()和free()都是库函数,因此不在编译器控制范围为内。然而,如果有一个完成动态内存分配及初始化组合动作的运算符和另一个完成清理及释放内存组合动作的运算符,编译器就可以保证所有对象的构造函数和析构函数都会被调用。

一、对象创建和销毁(new/delete) 对象创建(new)

当创建一个C++对象时,将会发生两件事:

1)为对象分配内存;

2)调用构造函数来初始化那个内存。

C++解决方案是吧创建一个对象的所有动作都结合在new运算符里。当用new创建一个对象时,它就在堆里为对象分配内存并为这块内存调用构造函数。

示例演示:

Type *ptr=new Type(2);

在运行时等价调用了malloc(sizeof(Type)),并使用2作为参数来为Type调用拷贝构造函数,this指针指向返回值的地址。在指针赋给ptr之前,它是不确定的、初始化的对象。它自动的被赋予正确的Type类型。

默认的new还进行检查以确保传递地址给构造函数之前内存分配完成。

对象销毁(delete)

new表达式的反面就是delete表达式进行对象销毁。delete表达式首先会调用析构函数,然后释放内存。

示例演示:

delete ptr

delete只用于删除由new创建的对象。如果用delete删除由malloc()创建的对象,这个动作行为是未定义的。

如果正在删除的对象的指针是0(NULL/nullptr),将不会发生任何事情。所以经常在删除指针后立即将指针赋值为0以免对它进行多次删除。

内存管理的开销

当在堆里创建对象需要一定的时间和空间开销。

首先会从堆上搜索一块足够大的内存来满足要求。这可以通过检查按某种方式排列的映射或目录来实现,映射和目录用来显示内存的使用情况。这个过程很快但可能要试探几次,所以它可能是不确定的,即每次运行malloc()并不是花费完全相同的时间。

在指向这块内存的指针返回之前,这块内存的大小和地址必须记录下来,这样以后调用malloc就不会使用它,而当调用free时,系统就知道释放多大的内存。

delete void*可能会内存泄漏

对一个void* 类型指针进行delete 操作,可能出错,因为它将不执行析构函数。

class Test { private: int* data; int size; public: Test(int len) :size(len) { data = new int[size]; cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3