C++中new、delete构件三种方式
发布日期:2021-06-30 12:11:04 浏览次数:3 分类:技术文章

本文共 2101 字,大约阅读时间需要 7 分钟。

1. new delete

1.1 new

分为两步:

  a、内存分配

    Ⅰ、内部调用全局的operator new(......)函数分配内存

               Ⅱ、如果类中重载了operator new(......)函数,则调用这个重载的函数

  b、构造函数
    再调用相应的构造函数 

 1.2 delete

       对应new方式的释放内存,分为两步

      a、析构函数

         调用一次析构函数

      b、释放内存

    Ⅰ、内部调用全局的operator delete(......)函数分配内存

               Ⅱ、如果类中重载了operator delete(......)函数,则调用这个重载的函数

2.array new、array delete

 2.1new [  ]

分为两步:

  a、内存分配

              Ⅰ、内部调用全局的operator new[](......)函数分配内存

               Ⅱ、如果类中重载了operator new[](......),则调用这个重载的函数

  b、构造函数
    每个对象各调用一次默认构造函数

 2.2delete [  ]

        对应new[]方式的释放内存,分为两步

      a、析构函数

         每个对象各调用一次析构函数

      b、释放内存

              Ⅰ、内部调用全局的operator delete[](......)函数分配内存

               Ⅱ、如果类中重载了operator delete[](......)函数,则调用这个重载的函数

#include 
using namespace std; class A{private: int id; public: A() :id(10) { cout << "default ctor.this=" << this << " id= " << id << endl; } A(int i) :id(i) { cout << "ctor.this=" << this << " id= " << id << endl; } ~A() { cout << "dtor.this=" << this << " id= " << id << endl; }}; int main(){ A *buf = new A[4]; // 分配内存并且调用默认构造函数 A *temp = buf; cout << "buf=" << buf << " temp=" << temp << endl; for (int i = 0; i < 4; ++i) { //这时候内存已经存在了,就单独调用重载的带一个int参数的构造函数 new(temp++) A(i + 1); // placement new } cout << "buf=" << buf << " temp=" << temp << endl; delete[] buf; return 0;}

3.placement new

 可以分配指定堆、栈、静态区的现有内存。

 堆区可以delete操作,但栈和静态区不可以delete操作

#include 
using namespace std; // 静态区//char *context[1024]{ 0 }; int main(){ // 使用静态区内存 //int *p = new (context) int[5]{ 1,2,3,4,5 }; //delete[] p; //erro // 使用堆区内存 char *context = new char[1024]{ 0 }; int *p = new (context+20) int[5]{ 1,2,3,4,5 }; delete[] p; //ok 释放所有的内存空间 // 使用栈区内存 //char *context[1024]{ 0 }; //int *p = new (context) int[5]{ 1,2,3,4,5 }; //delete[] p; //erro return 0;}

 placement new时内存已经分配好了,所以不存在placement delete,只是用delete或者delete[]释放内存即可

4、::new与new

        在全局命名空间中有一个自带的、隐藏的operator new专门用来分配内存。默认情况下编译器会将new这个关键字翻译成这个operator new和相应的构造函数。

  但在有的情况下,用户自己会在类中重载operator new,这种情况下,编译器默认会使用类中重载的operator new(本质上因为编译器会从命名空间由内而外查找自己想要的函数,选用第一个)。

  如果我们想要继续使用默认的operator new,就应该写成::new 字面意思就是调用最外层命名空间中的operator new

 值得一提的是最外层的(也是默认的)operator new也是可以被重载的。通过这种方式我们可以改变所有new的部分行为。

5.C++分配内存调用方式图

转载地址:https://jadeshu.blog.csdn.net/article/details/109410341 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:linux多线程
下一篇:C++模板、泛化、特化

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月27日 17时45分23秒