作者:baihacker
来源:http://hi.baidu.com/feixue
=============本站原创,转载请注明出处=============
今天有朋友在QQ群上说关于new重载的问题......
于是我就写了个程序分析一下
结论:重载new不好玩...要谨慎...何况这里还不是全局的new(全局new能玩死人的)
有意见请到我主页,加入黑色矩阵系列QQ群进行讨论
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
class A
{
int m_x;
int m_y;
public:
A(int x, int y) : m_x(x), m_y(y) {cout << "constructor in A" << endl;}
~A() {cout << "destructor in A" << endl;}
void* operator new (size_t n, int k);
void operator delete(void* p);
void show() {cout << m_x << ',' << m_y << endl;}//鸟的VC++6.0,bug多...尤其是友元...所以不重载<<,而用个函数了
};
void* A::operator new(size_t n, int k)
{
cout << "k = " << k << endl;
cout << "new in A" << endl;
return ::new A(1, 1);
}
void A::operator delete(void* p)
{
cout << "delete in A" << endl;
if (!p)
return;
else
::delete (A*)p;
}
int main()
{
A* a = new(1) A(3, 5);
a->show();
delete a;
system("pause");
return 0;
}
VC++6.0
编译警告:
warning C4291: 'void *__cdecl A::operator new(unsigned int,int)' : no matching operator delete found; memory will not be freed if initialization throws an exception
devc++
编译器: Default compiler
执行 g++.exe...
g++.exe "C:/Documents and Settings/Baihacker/桌面/未命名1.cpp" -o "C:/Documents and Settings/Baihacker/桌面/未命名1.exe" -g3 -I"D:/DevSoft/DevC++/Dev-Cpp/include/c++/3.3.1" -I"D:/DevSoft/DevC++/Dev-Cpp/include/c++/3.3.1/mingw32" -I"D:/DevSoft/DevC++/Dev-Cpp/include/c++/3.3.1/backward" -I"D:/DevSoft/DevC++/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include" -I"D:/DevSoft/DevC++/Dev-Cpp/include" -L"D:/DevSoft/DevC++/Dev-Cpp/lib" -g3
执行结束
成功编译
运行结果:
k = 1
new in A
constructor in A
constructor in A
3,5
destructor in A
delete in A
结果分析:
1.分析到new(1)后的A,确认内存的结构为A的一个实例的结构(前面的A* a并不能说明a指向的是一个真正的A的对象,完全有可能是A的子类的对象);
2.查找到A::operator new(size_t, int);(为什么调用时不显示地指出size_t呢...因为在编译时一定能确定这个参数,而且不可能是其它任何值,任何的改变都可能会有致命的错误,所以由编译器完成,所以只需要用户指出后面的参数了. 这样一方面注意了效率,一方面注意了安全,而后者是主要原因);
3.屏蔽全局的new,调用 A:: operator new;
4.编译时确定sizeof(A);
5.调用函数A::operator new(sizeof(A), 1);
6.把指针(返回值)赋给a;
7.调用一次a->A::A(3,5);