C++ new关键字运算符重载

复制代码
#include <iostream>
#include <vector>
#include <list>

class MyClass {
public:
    // 构造函数  
    MyClass(int value) : data(value) {
        std::cout << "MyClass constructor called with value " << data << std::endl;
    }

    // 析构函数  
    ~MyClass() {
        std::cout << "MyClass destructor called" << std::endl;
    }

    // 静态成员函数,用于重载new  
    void* operator new(size_t size) {
        void* p = malloc(size);
        std::cout << "Custom new called for MyClass, allocating " << size << " bytes at " << p << std::endl;
        return p;
    }

    // 静态成员函数,用于重载delete  
    void operator delete(void* p) noexcept {
        std::cout << "Custom delete called for MyClass, freeing memory at " << p << std::endl;
        free(p);
    }

    int data;
    std::list<int> arr;
};

int main() {
    MyClass* ptr = new MyClass(42);

    ptr->arr.push_back(1);

    delete ptr;


    return 0;
}
复制代码

在C++中,当你使用new运算符(无论是重载版本还是默认版本)来创建类的对象时,对象的构造函数会在分配内存之后、但在将内存地址返回给调用者之前被调用。这确保了对象在使用之前被正确地初始化。

上述例子发生的事情的顺序如下

MyClass::operator new(size_t size)被调用以在堆上分配足够的内存来存储MyClass对象。
分配的内存地址(由malloc或其他内存分配函数返回)被传递给构造函数MyClass(int value)。
MyClass(int value)构造函数在分配的内存上被调用,并使用提供的参数42来初始化对象。
构造函数完成后,new表达式返回指向新创建并初始化的对象的指针。
因此,构造函数是在内存分配之后但在将指针返回给调用者之前被调用的。这是确保对象在使用之前处于有效状态的重要步骤。

需要注意的是,如果你重载了new运算符但没有正确地处理内存分配失败的情况(例如,没有检查malloc的返回值是否为nullptr),并且内存分配失败,那么构造函数将不会被调用,因为根本没有分配内存来存储对象。

在这种情况下,你应该让重载的new运算符抛出异常(如std::bad_alloc),以便调用者可以适当地处理内存分配失败的情况。

posted on   寒魔影  阅读(37)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2016-06-28 C++ 类中的const关键字
2016-06-28 C++ 运算符重载四(自定义数组类)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示