跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ new 和delete 重载
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C++运算符重载:new和delete重载 = == 介绍 == 在C++中,'''new'''和'''delete'''运算符用于动态内存管理。与其他运算符一样,它们也可以被重载,允许程序员自定义内存分配和释放的行为。重载这些运算符在需要精细控制内存管理时特别有用,例如在嵌入式系统、高性能计算或实现自定义内存池时。 == 基本语法 == new和delete运算符可以以成员函数或全局函数的形式重载。以下是基本语法: <syntaxhighlight lang="cpp"> // 全局重载 void* operator new(size_t size); void operator delete(void* ptr) noexcept; // 类成员重载 class MyClass { public: void* operator new(size_t size); void operator delete(void* ptr) noexcept; }; </syntaxhighlight> == 重载new运算符 == 重载new运算符时,必须返回void*,并接受一个size_t参数(表示要分配的字节数)。下面是一个简单的全局new重载示例: <syntaxhighlight lang="cpp"> #include <iostream> #include <cstdlib> void* operator new(size_t size) { std::cout << "自定义new分配了 " << size << " 字节\n"; void* ptr = malloc(size); if (!ptr) throw std::bad_alloc(); return ptr; } int main() { int* p = new int(42); std::cout << "*p = " << *p << "\n"; delete p; return 0; } </syntaxhighlight> 输出: <pre> 自定义new分配了 4 字节 *p = 42 </pre> == 重载delete运算符 == delete运算符重载必须返回void,接受一个void*参数(指向要释放的内存),并且应该标记为noexcept: <syntaxhighlight lang="cpp"> void operator delete(void* ptr) noexcept { std::cout << "自定义delete释放内存\n"; free(ptr); } </syntaxhighlight> == 数组版本 == 也可以重载new[]和delete[]: <syntaxhighlight lang="cpp"> void* operator new[](size_t size) { std::cout << "自定义new[]分配了 " << size << " 字节\n"; void* ptr = malloc(size); if (!ptr) throw std::::bad_alloc(); return ptr; } void operator delete[](void* ptr) noexcept { std::cout << "自定义delete[]释放内存\n"; free(ptr); } </syntaxhighlight> == 类特定重载 == 在类内部重载new和delete时,这些运算符仅适用于该类的对象: <syntaxhighlight lang="cpp"> class MemoryTracker { public: void* operator new(size_t size) { std::cout << "为MemoryTracker分配 " << size << " 字节\n"; return ::operator new(size); // 使用全局new } void operator delete(void* ptr) noexcept { std::cout << "释放MemoryTracker内存\n"; ::operator delete(ptr); // 使用全局delete } }; </syntaxhighlight> == 放置new == 除了常规new,还可以重载'''放置new'''(placement new),它允许在已分配的内存上构造对象: <syntaxhighlight lang="cpp"> #include <new> void* operator new(size_t size, void* ptr) noexcept { return ptr; // 只是返回传入的指针 } // 使用示例 int main() { char buffer[sizeof(int)]; int* p = new (buffer) int(42); // 在buffer上构造int std::cout << *p << "\n"; p->~int(); // 显式调用析构函数 return 0; } </syntaxhighlight> == 实际应用案例 == === 内存池实现 === 重载new和delete常用于实现'''内存池''',提高频繁分配/释放小对象时的性能: <syntaxhighlight lang="cpp"> class MemoryPool { struct Block { Block* next; }; Block* freeList = nullptr; public: void* allocate(size_t size) { if (!freeList) { // 分配大块内存并分割 freeList = static_cast<Block*>(malloc(1024)); for (int i = 0; i < 1024/sizeof(Block); ++i) { freeList[i].next = &freeList[i+1]; } freeList[1024/sizeof(Block)-1].next = nullptr; } Block* block = freeList; freeList = freeList->next; return block; } void deallocate(void* ptr) noexcept { Block* block = static_cast<Block*>(ptr); block->next = freeList; freeList = block; } }; class PooledObject { static MemoryPool pool; public: void* operator new(size_t size) { return pool.allocate(size); } void operator delete(void* ptr) noexcept { pool.deallocate(ptr); } }; </syntaxhighlight> === 内存泄漏检测 === 通过重载new和delete可以实现简单的内存泄漏检测: <syntaxhighlight lang="cpp"> #include <iostream> #include <map> std::map<void*, size_t> allocations; void* operator new(size_t size) { void* ptr = malloc(size); allocations[ptr] = size; std::cout << "分配: " << ptr << " (" << size << " 字节)\n"; return ptr; } void operator delete(void* ptr) noexcept { auto it = allocations.find(ptr); if (it != allocations.end()) { std::cout << "释放: " << ptr << " (" << it->second << " 字节)\n"; allocations.erase(it); } free(ptr); } void checkLeaks() { if (!allocations.empty()) { std::cerr << "内存泄漏检测到 " << allocations.size() << " 个未释放块:\n"; for (const auto& [ptr, size] : allocations) { std::cerr << " " << ptr << ": " << size << " 字节\n"; } } } </syntaxhighlight> == 注意事项 == * 重载new和delete会影响整个程序的内存管理,需谨慎使用 * 确保重载的delete标记为noexcept * 重载new应该正确处理内存不足情况(抛出bad_alloc) * 类特定重载优先于全局重载 * 重载placement new时需要提供对应的placement delete == 性能考虑 == 重载内存管理运算符可能带来性能提升,但也可能引入开销。考虑以下因素: * 自定义内存池可以减少系统调用 * 额外的簿记工作会增加内存使用 * 线程安全性需要考虑 == 总结 == 重载new和delete运算符是C++提供的一个强大特性,允许程序员完全控制内存管理。通过合理使用这一特性,可以实现: * 自定义内存分配策略 * 内存使用跟踪和调试 * 特定领域的内存优化 * 资源管理扩展 对于大多数应用程序,标准的内存管理已经足够,但在需要特殊内存处理的情况下,重载这些运算符提供了极大的灵活性。 [[Category:编程语言]] [[Category:C++]] [[Category:C++ 运算符重载]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)