zoukankan      html  css  js  c++  java
  • c++中new的知识点

    在练习内存池时,发现需要重载new,可是这个重载只是重载了operator new,那么还有哪几种new呢,下面来记录一下

    首先记录一个点,在类中重载operator new,默认就是静态成员函数,所以不能生命为虚函数,不能调用非静态成员变量

    下面正文,c++有三种new

    说的通俗点。1、new运算符(new operator)大哥,我们在代码中直接使用的就是它。它做2件事:调用后两种new申请内存和初始化对象。2、operator new,是一个函数,所以也是三种new唯一一个可以重载的。它类似C语言中的malloc,用于分配内存。3、placement new,用于初始化对象(如果有的话,就是它调用构造函数)

    1.operator new

    operator new和operator delete有两个重载版本,每个版本支持相关的new表达式和delete表达式:

    void *operator new(size_t);
    
    void *operator new[](size_t);
    
    void *operator delete(void*);
    
    void *operator delete[](void*);

    入参类型必须为size_t,返回类型必须为void *.可以重载为多个参数版本如下

    void *operator new(size_t t1,size_t t2);
    这样如果调用未 void *p= new(10) int;时 t2的大小就为10.而t1的大小一直是固定的(可能根据系统不同而变化)
    这个是我们唯一可以重载的new,不仅可以在类内重载,全局operator new也可以被重载。如果全局operator new被重载的话,那么除了类内的重载会覆盖全局的重载,任何地方调用new 都会调用到这个全局重载的函数里

    2.new operator
    当你写string *ps = new string(“Hands up!”)时,你所使用的new是所谓的new operator,它其实干了两件事:
    一、分配足够的内存(实际大小是大于所创建的对象大小,因为有管理的数据),即operator new。
    二、调用对象构造函数,new operator永远干这两件事。上面的那段代码大约反映以下的行为
    void *mem = operator new(sizeof(string));
    call string::string(“Hands up!”) on *mem;//只能由编译器完成,用户是不允许这样操作的,也就是说如果你想建立一个堆对象就必须用new操作符,不能直接像上面一样调用构造函数来初始化堆对象。

    也就是说operator new仅仅分配内存(就像malloc一样),我们能够做的仅仅是重载operator new,为自己的类创建一个定制的内存管理方案,
    这也让我有点明白为什么在重载operator new的时候并没有写调用构造函数的代码,但它确实被调用了,原来都是new operator搞的鬼。

     编译器看到类类型的new或者delete表达式的时候,首先查看该类是否是有operator new或者operator delete成员,如果类定义了自己的new和delete函数,则使用这些函数为对象分配和释放内存,否则调用标准库版本。如果你想定制自己独有的内存分配过程,你应该重载全局的operator new函数,然后使用new操作符,new操作符会调用你定制的operator new。当然你可以显示的调用:: operator new和:: operator delete强制使用全局的库函数

    3.定位new表达式

    即placement new,定位new表达式在已分配的与原始内存中初始化一个对象,他与new的其他版本不同,它不分配内存。相反,它接受指向已分配好但未构造的内存指针,并在该内存中初始化一个对象。实际上,定位new表达式使我们在特定的、预分配的内存地址构造一个对象。它可以定义类的任何构造函数。

             new(place_address) type
    
             new(place_address) type(initializer_list)

    举个例子,

    我们也可以直接来使用它,你手上有一块内存p。int *p2 = new (p) int(100); 这样你就用placement new把一块内存初始化为int,并给它个初值100。其实这里,p所指向的内存可以是堆也可以是栈。如果是栈内存被这样new,不需要delete,且可以反复的new。这有什么用, 你可以把动态分配内存的请求限制在一块区域内,这就有点像操作系统给引用程序分配内存,这一块给你随便用, 妨碍不到其他的内存。算是一种安全策略吧。

  • 相关阅读:
    vue-cli搭建项目结构及引用bootstrap
    万年历案例
    art-template模板渲染及其过滤器
    字符串中全角半角之间的转换
    大话主席(superslide和 touchslide)插件的使用
    JS中对URL进行转码与解码
    animate.css引入实现动画效果
    [MySQL]group by 与 having 结合函数 的统计技巧
    [HTTP] 基本认证的工作流程
    [HTTP]Etag的工作流程
  • 原文地址:https://www.cnblogs.com/wangshaowei/p/11583510.html
Copyright © 2011-2022 走看看