• C++ 关键字 new


    new

    new 是C++ 中的关键字,有两个含义

    1. new 表达式
    2. 作为运算符的函数名,也就是 operator new

    new 表达式

    提供一个特定的内存分配格式,返回在存储空间上构造的对象或对象数组的一个 纯右值 指针。

    语法

    • :: (可选) new (布置参数)(可选) (类型) 初始化器(可选)
    • :: (可选) new (布置参数)(可选) 类型 初始化器(可选)

    说明

    1. 布置参数为分配的内存
    2. 初始化器则有两种,分别是(){} 初始化方式,可以包括 auto decltype(auto) 等占位类型说明符
    char* ptr = new char[sizeof(T)]; // 分配内存
    T* tptr = new(ptr) T;            // 在已分配存储中构造(“布置”)
    tptr->~T();                      // 销毁
    delete[] ptr;                    // 解分配内存
    

    一些注意点

    1. 表达式中的 类型为贪心,比如 new int * 1 实际上是 int 先结合 *,(这个会编译失败)。
    2. 在对象数组分配内存时,一维之外的维数必须指定为整数常量。
    3. new 表达式是为对象分配是调用 operator new 来完成,对象的大小可以在编译期得到 (开优化),之后进行对象的构造,构造过程的规则无特殊之处。

    operator new

    new 表达式通过调用 operator new 来分配内存,分配对象数组为 operator new[].

    C++ 自身提供了全局的函数(以::开始),和用户自定义的替换函数,如果 new T; 中T为类类型,则从T的类作用域中开始查找替换函数。

    基本的函数格式如下:

    void* T::operator new  ( std::size_t count );
    

    这里我们自定义一个例子,operator new 是我们自定义的分配函数,后面部分是对在已经分配的内存上进行再分配的情况

    • 在已有内存上分配空间,不会再调用分配函数,
    • 每次分配的内存地址都相同。
      所以每次调用默认布置分配函数的时候,只是一个内存控制权的转移,这段内存的生命生命周期应该在其上构造对象之后。
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    
    void *operator new(size_t n) {
        printf("operator new: %zu
    ", n);
        return std::malloc(n);
    }
    struct Foo {
        uint64_t valu64;
        int64_t vali64;
        char ch;
    
        Foo() : valu64(1), vali64(3), ch('c') {}
    };
    
    int main() {
        char *ptr = new char[16]; // std::malloc(16);
        Foo *tptr = new (ptr) Foo; // 在已分配存储中构造(“布置”), 这里有溢出风险
        tptr->~Foo(); // 销毁
        delete[] ptr; // 解分配内存
    
        Foo *fp = new Foo; // std::malloc(24);
    
        char arr[36];
        printf("init arr addr: %p
    ", arr); // 0x7ffe8f9748e0
        Foo *fptr = new (arr) Foo;
        printf("Foo addr: %p
    ", fptr); // 0x7ffe8f9748e0
        char *ch = new (arr) char;
        printf("ch addr: %p
    ", ch); // 0x7ffe8f9748e0, 三者的地址是一样的
        fptr->~Foo();                // 销毁
    }
    

    参考

    1. new. C++ 关键字 new.

    // 过年疫情导致不能出门,在家里学习学习,记点笔记。

  • 相关阅读:
    C# winForm webBrowser页面中js调用winForm类方法(转)
    Shader开发工具: PVRShaman
    创建压缩纹理的工具
    Andriod NDK编译的时候无法使用math.h的函数。
    mongodb自动关闭:页面文件太小,无法完成操作
    通读cheerio API
    How to skip to next iteration in jQuery.each() util?
    在javascript中substr和substring的区别是什么
    运行代码时报linker command failed with exit code 1 错误
    软件开发模式对比(瀑布、迭代、螺旋、敏捷)
  • 原文地址:https://www.cnblogs.com/shuqin/p/12234739.html
Copyright © 2020-2023  润新知