惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
IT之家
IT之家
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
L
LangChain Blog
博客园 - Franky
美团技术团队
J
Java Code Geeks
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
小众软件
小众软件
Y
Y Combinator Blog
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
Docker
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News

博客园 - 寒魔影

Linux waitpid函数分析 不同进程内相同的变量内存地址是相同的 Linux 内存虚拟地址介绍 Sword B树学习笔记二 Sword B树学习笔记一 defined but not used警告屏蔽 apisix流量高峰期服务卡住问题 服务卡死现象分析实录 服务资源加载延迟异常增加 Linux 常用命令四 TCP全连接队列 调用writev收到信号SIGPIPE问题分析记录 epoll_wait监听事件延迟问题记录 writev发送数据失败 Missing separate debuginfos类型崩溃分析 宏定义导致数据异常问题 服务压测偶现卡住问题分析 C语言 数据类型 Linux 终端光标控制函数
C++ new关键字运算符重载
寒魔影 · 2024-06-28 · via 博客园 - 寒魔影
#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),以便调用者可以适当地处理内存分配失败的情况。