C++ new 和 delete 的重载

发现:类里面有几种成员函数是没有this指针的,也就是访问不了类的成员
 构造函数:有; 说明其实对象真正的初始化就是在初始化类表
 析构函数:有; 析构函数在最后的时刻才把对象空间释放
 普通函数:有
 static函数: 没有,但能访问静态成员
 重载的 new new[]成员函数: 没有, 因为对象的产生是先有空间在调用构造函数,new就是完成前个步骤的工作
 重载的 delete  delete[]成员函数: 没有, 因为对象的消失是先调用析构函数在回收对象空间,delete就是完成后面步骤的工作
 ......
  
new new[] delete delete[]在C++ 中是运算符,和sizoeof
底层的实现是通过C的malloc和free来实现的
存在的意义: C++ 中引入类,类的两个重要的函数:构造函数和析构函数
new  或 new[] 对象或一系列对象时, new操作符工作:1)先申请足够容纳存储对象的空间
  2)依次调用类的无参构造函数,所以类中要有无参构造函数


delete 或 delete[]: 1) 当面对释放的类型是基本类型的时候,两者是一样的效果
2)delete 和 delete[] 跟 free 最大的区别就是先调用类的析构函数析构对象
然后再执行free的操作,回收对象所存储的空间(注意:如果类中有指向堆空间的指针,这个操作是必须的)'
delete 对象 ,就是调用该对象的析构函数,在释放对象占用的空间
delete[]对象,如果对象是一系列对象,则循环调用每个对象的析构函数,再释放空间


new 和 delete的重载: 1)特定类中的重载; 2)全局范围的重载
new 通常的重载方式--> void* operator new(size_t size);
 可以在重载函数中加入其他参数,但第一个参数必须是size_t

 类型


下面的代码是参考自:http://blog.sina.com.cn/s/blog_3f56d7800100i1uf.html

/*
 * =====================================================================================
 *
 *       Filename:  new_delete_trace.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  08/22/2012 12:26:42 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  lsff (lsff), 
 *   Organization:  
 *
 * =====================================================================================
 */
#include <cstdlib>
#include <iostream>
using namespace std;

#define _DEBUG
#ifdef _DEBUG
void *operator new(size_t size, const char* file, int line)
{
cout<<"new size:"<<size<<endl;
cout<<file<<" "<<line<<endl;
// return mallloc(size);
return operator new(size);
}

void *operator new[](size_t size, const char* file, int line)
{
cout<<"new size:"<<size<<endl;
cout<<file<<" "<<line<<endl;
void *p = malloc(size);
cout<<reinterpret_cast<long>(p)<<endl;;
// return mallloc(size);
return p;
}
void operator delete(void *p)
{
long ip =reinterpret_cast<long>(p);
cout<<"delete "<<ip<<endl;
free(p);
}
void operator delete[](void *p)
{
cout<<"delte[]"<<reinterpret_cast<long>(p)<<endl;
free(p);
}

// 注意:上面连个函数体虽然相同,但一个都不能少
// delete[] 可以认为系统看到这个函数,就会循环地去调用该空间的
// 每个对象的析构函数再释放空间,但是delete 就只是调用第一个对象
// 的析构函数就释放空间,所以可以认为[] 区别了系统怎样去调用
// 底层的free,因为free 对数组和单个元素是不区分的,但是在free之前
// 系统通过[] 完成类似free的智能操作

void operator delete(void *p,const char*file ,int line)
{
cout<<"delete "<<file<<" "<<line<<endl;
free(p);
}

void operator delete[](void *p,const char*file ,int line)
{
cout<<"delete[] "<<file<<" "<<line<<endl;
free(p);
}
//上面两个函数是有用的,在异常发生的时候,默默无闻啊~~~

#define new  new(__FILE__, __LINE__)
#endif


class test
{
private:
int ival;
public:
test(){
throw int(3);
}
~test()
{
cout<<__FUNCTION__<<endl;
}
};

int  main()
{
// int *p=new int[5];
// delete (p);
// test *pc = new test[5];
// delete []pc;  // pc是指向对象的数组时必须使用delete[],这样才会以此调用构造函数
try{
test *pc = new test;

delete pc;
}
catch(int a)
{
}
return 0;
}

### newdelete的基本使用 在C++中,`new``delete`运算符用于动态内存管理。它们不仅负责分配释放内存,还负责调用对象的构造函数析构函数。这与C语言中的`malloc``free`不同,后者仅处理内存分配而不涉及对象的构造析构。 #### 使用`new`进行内存分配 使用`new`分配内存时,可以指定数据类型,并且会自动计算所需内存大小。例如,分配一个整型变量: ```cpp int* p = new int; ``` 对于数组,可以使用如下语法: ```cpp int* arr = new int[10]; ``` 当使用`new`分配内存时,如果内存不足,会抛出`std::bad_alloc`异常。为了避免程序崩溃,可以在分配内存时使用`nothrow`参数: ```cpp int* p = new (std::nothrow) int; ``` #### 使用`delete`进行内存释放 释放由`new`分配的单个对象内存: ```cpp delete p; ``` 释放由`new[]`分配的数组内存: ```cpp delete[] arr; ``` ### newdelete工作原理 #### `new`操作符 `new`操作符的主要职责是: 1. 调用`operator new`来分配内存。 2. 调用相应的构造函数来初始化对象。 `operator new`是一个全局函数,其默认实现类似于`malloc`,但会抛出异常而不是返回`NULL`。如果内存分配失败,它会调用`new_handler`函数,尝试释放一些内存并再次分配。 ```cpp void* operator new(std::size_t size); ``` #### `delete`操作符 `delete`操作符的主要职责是: 1. 调用相应的析构函数来清理对象。 2. 调用`operator delete`来释放内存。 ```cpp void operator delete(void* ptr); ``` `operator delete`的默认实现类似于`free`,用于释放由`operator new`分配的内存。 ### newdelete的区别 1. **构造与析构**:`new`不仅分配内存,还会调用对象的构造函数;`delete`不仅释放内存,还会调用对象的析构函数。而`malloc``free`仅处理内存分配释放,不涉及构造析构。 2. **异常处理**:`new`在内存不足时会抛出`std::bad_alloc`异常,而`malloc`返回`NULL`。 3. **类型安全**:`new`返回的是具体类型的指针,不需要显式类型转换;`malloc`返回的是`void*`,需要显式类型转换[^1]。 ### newdelete的实现原理 `new``delete`的底层实现依赖于`operator new``operator delete`。`operator new`的默认实现使用`malloc`来分配内存,并在分配失败时抛出异常。`operator delete`的默认实现使用`free`来释放内存[^4]。 对于自定义类型的对象,`new`会在分配的内存上调用构造函数,而`delete`会在释放内存前调用析构函数[^3]。 ### 定位new表达式(Placement-new) 有时需要在已分配的内存中构造对象,这时可以使用定位`new`表达式。例如: ```cpp char buffer[sizeof(MyClass)]; MyClass* obj = new (buffer) MyClass; ``` 此代码在`buffer`中构造了一个`MyClass`对象,而不会分配新的内存[^2]。 ### 内存泄漏 内存泄漏是指程序在运行过程中分配了内存但未能正确释放,导致内存浪费。内存泄漏的危害包括程序性能下降、系统资源耗尽等。为了避免内存泄漏,应确保每次`new`操作都有对应的`delete`操作,并使用智能指针等现代C++特性来管理内存。 ### 相关问题 1. 如何在C++中避免内存泄漏? 2. 什么是定位new表达式?它的应用场景是什么? 3. `operator new``operator delete`可以被重载吗?为什么? 4. `new``malloc`的主要区别是什么? 5. 在什么情况下应该使用`new (nothrow)`? [^1]: 参考站内引用:引用[1] : 参考站内引用:引用[2] [^3]: 参考站内引用:引用[3] [^4]: 参考站内引用:引用[4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值