当前位置: 首页 > article >正文

C++:operator new/delete函数

每个类默认都会有一个全局范围的 operator newoperator delete 接口,它们是由标准库提供的,可以用于动态内存分配和释放。如果一个类没有显式定义自己的 operator newoperator delete,默认的全局版本会被使用。


默认 operator new 的特点

  1. 定义

    • 默认的 operator new<new> 头文件中定义。
    • 它分配一块指定大小的内存(以字节为单位),并返回其地址。
  2. 实现(概念上):

    void* operator new(std::size_t size) {
        if (void* p = std::malloc(size)) // 使用 malloc 分配内存
            return p;
        throw std::bad_alloc();         // 如果分配失败,抛出异常
    }
    
  3. 全局版本
    默认情况下,所有类都使用全局范围的 operator newoperator delete

    void* operator new(std::size_t size);
    void operator delete(void* ptr) noexcept;
    
  4. 例子

    class MyClass {
    public:
        int x;
    };
    
    MyClass* obj = new MyClass();  // 使用全局的 operator new 分配内存
    delete obj;                    // 使用全局的 operator delete 释放内存
    

自定义 operator new

可以为某个类自定义 operator newoperator delete,从而覆盖默认行为。例如:

  1. 自定义类专属的 operator new

    class MyClass {
    public:
        void* operator new(std::size_t size) {
            std::cout << "MyClass::operator new called\n";
            return std::malloc(size); // 自定义内存分配逻辑
        }
    
        void operator delete(void* ptr) noexcept {
            std::cout << "MyClass::operator delete called\n";
            std::free(ptr); // 自定义内存释放逻辑
        }
    };
    
    MyClass* obj = new MyClass();  // 调用 MyClass 自定义的 operator new
    delete obj;                    // 调用 MyClass 自定义的 operator delete
    
  2. 自定义操作对其他类的影响

    • 自定义的 operator newoperator delete 只适用于该类及其派生类,不会影响其他类或全局的内存分配行为。
    • 如果调用的是全局范围的 newdelete,将使用默认版本。

全局 operator new

除了类的自定义版本,可以重载全局范围的 operator newoperator delete

  1. 重载全局版本

    void* operator new(std::size_t size) {
        std::cout << "Global operator new called\n";
        return std::malloc(size);
    }
    
    void operator delete(void* ptr) noexcept {
        std::cout << "Global operator delete called\n";
        std::free(ptr);
    }
    
  2. 影响范围

    • 所有未自定义 operator new 的类都会使用全局版本。

注意事项

  1. 静态对象和栈对象

    • 对于静态或栈分配的对象,operator newoperator delete 不会被调用。
    • 它们只针对动态分配的内存。
    MyClass obj;  // 不会调用 operator new 或 operator delete
    
  2. 继承与多态

    • 如果基类和派生类分别定义了 operator new,则会根据具体类调用对应的版本。
  3. 内存对齐

    • 默认版本的 operator new 保证分配的内存满足类型的对齐要求。
    • 如果需要特殊对齐,可以重载带对齐参数的 operator new

总结

  1. 默认的 operator newoperator delete 是全局提供的,所有类默认都会使用它们。
  2. 可以自定义某个类的 operator newoperator delete,以满足特定的内存分配需求。
  3. 对于动态内存管理,C++ 提供了很高的灵活性和可控性,但同时需要谨慎处理以避免内存泄漏和错误。

http://www.kler.cn/a/404648.html

相关文章:

  • 科研实验室的数字化转型:Spring Boot系统
  • sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面
  • php:使用socket函数创建WebSocket服务
  • Ubuntu20.04从零安装IsaacSim/IsaacLab
  • 【生成数据集EXCEL文件】使用生成对抗网络GAN生成数据集:输出生成数据集EXCEL
  • Python之time时间库
  • 前端面试之九阴真经
  • 金融量化交易领域,许多开源平台提供了图形用户界面(GUI)
  • Java-异常处理机制-throws
  • 【PCIE常见面试问题-1】
  • SpringBoot(三十三)SpringBoot集成Spring boot actuator程序监控器
  • 如何查找 Kafka消息队列中主题Topic的消费者?
  • C#高级:通过反射判断列表中指定字段是否存在空值
  • 笔记记录 k8s-RBAC
  • MySQL最后练习,转转好物交易平台项目
  • wpf中几种获取ComBox中值的方法
  • 机器学习基础06_梯度下降
  • 基于Java Springboot导师选择管理系统
  • Palo Alto Networks PAN-OS身份认证绕过导致RCE漏洞复现(CVE-2024-0012)
  • 【golang-技巧】- context 使用
  • spacy 安装 en_core_web_sm
  • MySQL中有哪几种锁?
  • Linux基础指令(汇总)
  • StarRocks 架构
  • Flutter:AnimatedPadding动态修改padding
  • 云原生之k8s服务管理