关于重载new delete new[] delete[]笔记----C++学习之路

  1.在之前的笔记中已经提到,new在编译器下会分成三个动作,当有重载就会跑到重载之中。

先看一个代码:

void* myAlloc(size_t size)
{
    renturn malloc(size);
}

void myFree(void* ptr)
{
    return free(ptr);
}
再看一个重载:

inline
void* operator new(size_t size)
{
    return myAlloc(size);
}
inline
void* operator new[](size_t size)
{ 
     return myAlloc(size);
}
inline
void operator delete(void* ptr)
{
    myFree(ptr);
}
inline
void operator delete[](void* ptr)
{ 
    myFree(ptr);
}
这里要注意一个影响,现在我们是在重载一个全局的东西。

  2.当然我们还能重载member中的new与delete。

class Foo
{
public:
    void* operator new[](size_t);
    void operator delete[](void* ptr);
    ...
};
应用:

Foo* p = new Foo[N];
delete[] p;

这里讨论new[]与delete[]

当Foo* p = new Foo[N];

会调用Foo::Foo() N次。

  3.看看具体的示例:

class Foo
{
public:
    int _id;
    long _data;
    string _str;
public:
    Foo():_id(0) {cout<<"default ctor.this="<<this<<"id="<<_id<<endl;}
    Foo(int i):_id(i) {cout<<"ctor.this="<<this<<"id="<<_id<<endl;}

    ~Foo() {cout<<"ctor.this="<<this<<"id="<<_id<<endl;}
    static void* operator new(size_t size);
    static void operator delete(void* pdead,size_t size);
    static void* operator new[](size_t size);
    static void operator delete[](void* pdead,size_t size);
};
void* Foo::operator new(size_t size)
{
    Foo* p = (Foo*)malloc(size);
    return p;
}
void Foo::operator delete(void* pdead,size_t size)
{
    free(pdead);
}
void* Foo::operator new[](size_t size)
{
    Foo* p = (Foo*)malloc(size);
    return p;
}
void Foo::operator delete[](void* pdead,size_t size)
{
    free(pdead);
}
假设使用:

Foo* pf = new Foo;
delete pf;

//如果使用者想要绕过这些重载
Foo* pf = ::new Foo;
::delete pf;
//这样就会调用全局的:
void* ::operator new(size_t);
void ::operator delete(void*);
可以看到一个Foo占有12字节。
单纯从代码很难看出端倪,我们去编译器中具体运行一下试试:

#include "stdafx.h"
#include "Foo.h"

int main()
{

	Foo *pa = new Foo();
	cout << endl;
	delete pa;
	cout << endl;
	cout << endl;
	Foo *pb = new Foo[5];
	cout << endl;
	delete[] pb;
    return 0;
}
结果图:


这里就能很清楚的看清楚new delete 与new[] delete[] 的区别。

  4.具体讨论一下关于sizeof的关系。

分两种情况:

(1)Foo without virtual

Foo *pa = new Foo();
Foo *pb = new Foo[5];
我们直到在Foo中有三个数据,一共是12个字节,那么第一行代码的pa必然是12字节,

但是,pb理论上应该是60字节,但是却占有64个字节,为什么?因为还有一个4字节的内存上显示5,代表有五个。

(2)Foo with virtual

如同上一个那样运行,我们会发现,pa是占有16字节内存,为什么?如同之前关于虚机制的vptr vtbl的笔记中有说,虚函数的类中肯定会有一根vptr。

pb中占有84字节!!!!
  5.再来验证一下关于绕过自己重载的new与delete

我们先在重载的new delete中都加上:cout<<"1"<<endl;

运行之前的调用:


运行绕过的代码:

// 关于重载new与delete.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Foo.h"

int main()
{

	Foo *pa = ::new Foo();
	cout << endl;
	::delete pa;
	cout << endl;
	cout << endl;
	Foo *pb = ::new Foo[5];
	cout << endl;
	::delete[] pb;

	
    return 0;
}
运行结果:








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值