new&delete

new和delete的基本用法:

#include <iostream>
#include <stdlib.h>
#define N 10

using namespace std;
class test
{
private:
    int a;
public:
    test(int d=0)
    {
        a=d;
        cout<<"构造函数"<<endl;
    }
    ~test()
    {
        cout<<"析构函数"<<endl;
    }
};
int main()
{
//一个变量空间
    int *p=(int*)malloc(sizeof(int ));
    if(p==NULL)//malloc开辟空间需要判断一下是否成功,new不需要
    {
        exit(1);
    }
    *p=2;
    free(p);

    int *q=new int(2);//如果new一个变量可以在初始化的时候赋值,
    delete q;

//一个数组
    int *p2=(int *)malloc(sizeof(int )*N);
    if(p2==NULL)
    {
        exit(1);
    }
    free(p2);

    int *q2=new int[N];//不要和上面的圆括号混淆了
    delete []q2;//前面加一个[]来区分是一个变量还是数组;(方括号里面的数字没用.编译器自动忽略.无聊的话可以随便填....)

//一个对象
    test* p3=(test*)malloc(sizeof(test));
    if(p3==NULL)
        exit(1);
    *p3=test(3);//见下面
    //如果对象里面有指针变量,这里必须释放对象内部指针变量指向的空间,相当与析构函数的功能;
    free(p3);
cout<<"上面是malloc,下面是new"<<endl;
    test* q3=new test;
    delete q3;
/*跑一遍你会发现
malloc没有调用构造析构函数,只会申请空间,
new,申请空间,并会调用相应的构造函数.

malloc free没有调用构造析函数,就没有完成相应的对象初始化和析构变量(对对象内部指针变量的释放);
所以就要在内存申请完毕后再对对象进行初始化,在free前要对对象内部的指针变量进行释放,否则就会造成内存泄露;
*/
    test* q4=new test[N];//new的时候我们没办法给出初始化的参数(构造函数的参数),所以我要使用new数组的时候对象必须要有默认(无参)的构造函数;
    delete []q4;//再次提醒数组一定要加[];

    cout << "Hello world!" << endl;
    return 0;
}

new的深入理解
对于new的重载,operator new 和 定位new;

#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class test
{
private:
    char *a;
public:
    test(const char *const d="")
    {
        if(d==NULL)
        {
            a=new char[1];
            a[0]=0;
        }
        else
        {
            a=new char[strlen(d)+1];
            strcpy(a,d);
        }
        cout <<"构造函数"<<endl;
    }
    ~test()
    {
        delete []a;
        a=NULL;
        cout <<"析构函数"<<endl;
    }
  //  void * operator new(size_t len);
  //  void operator delete(void * p);

};
/*
前面我们说过 new 在调用的时候会首先开辟空间(而且底层还是malloc实现),然后再调用构造函数.
这个就是我们经常使用的new,叫做new operator(new 操作符);delete也是一样的,顺序与new相反(先调用析构函数,在对地址进行释放);

那么,new是怎么开辟空间的呢?
new在开辟空间时 调用的是operator new(操作符new);(operator new 在汇编是用malloc实现);
我们知道了两个new的区别,但这个operator new 有什么用呢?
new和delete都是用算符,可以被重载,我们说的operator new就是这个用法,我们可以重载operator new 来自己定义new开辟开辟空间的方法;
*/
void * operator new(size_t len)//size_t 就是 int ,这里要说 第一个参数 必须是一个无符号整形;返回类型是void* 需要在返回的地方进行强转
{
    cout<<"operator new"<<endl;
    void *p=malloc(len);
    return p;
}
void operator delete(void * p)
{
    cout <<"operator delete"<<endl;
    free (p);
}
//对与数组的operator new;
void * operator new[](size_t len)
{
    cout <<"operator new []"<<endl;
    void *p=malloc(len);
    return p;
}
void operator delete[](void *p)
{
    cout <<"operator delete []"<<endl;
    free(p);
}
//定位new的重载
template <typename type>
void * operator new (size_t len,type *d,int n=0)//讲type类型的指针传入进来,返回需要构造的地址,他会自己给你构造.
{
    return d+n;
}
int main()
{
    //test p("wahaha\n");

    test *p1=new test("wahaha1/n");
    delete p1;
//我们会发现使用 new操作符 时会向我们说的先调用 操作符new 来开辟空间,然后再调用析构函数;delete也是一样.
//就像下面的过程一样
    test * p2=(test *)operator new(sizeof(test));//先用 operator new 开辟空间
    new(p2)test("wahaha2/n");//这里是new的第三种用法,叫做定位new

    p2->~test();//主动调用析构函数,但是构造函数不能主动调用,所以上面构造对象 使用了定位new的用法
    operator delete(p2);//释放空间

    test *p3=new test[3];//对数组的使用
    delete []p3;

//定位new,是可以将你传入的指针的地方进行一次构造函数,
    int aa[10];
    new(aa,3)int(4);
    new(aa,4)int(1234);
    new(aa)int(34);
for(int i=0;i<10;i++)
    cout <<aa[i]<<endl;
    cout << "Hello world!" << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值