- new运算符
- Operator new()函数
- placement new
我们平时调用的new运算符底层调用的就是Operator new()函数(功能和malloc一模一样),如果是内置类型或者没有重载new运算符的自定义类型,那么将调用全局Operator new(),如果重载了将调用局部的Operator new(),如果这个类型有构造函数,new还是调用构造函数(注意调用构造函数之前还会吧operator new()的返回值检查一下,如果等于0那么就不调用构造函数)
验证1:new运算符底层调用的就是Operator new()函数
class A
{
public:
A(){ cout << "构造" << endl; }
int a;
};
int test2()
{
A *b = new A;
return 0;
}
验证2:内置类型或者没有重载new运算符的自定义类型,那么将调用全局Operator new(),重载了将调用局部的Operator new()
没有重载的汇编代码刚才已经看了,现在看一个重载之后的。
区别很明显吧!!
验证3:如果这个类型有构造函数,new还是调用构造函数
还是第一段代码
第二段代码(没有构造)
再看一个内置类型,和上面一模一样
验证4:构造函数之前还会吧operator new()的返回值检查一下,如果等于0那么就不调用构造函数
我们来重载一下new操作符
class A
{
public:
A(){ cout << "构造" << endl; }
int a;
void * operator new(size_t size)
{
cout << "dong" << endl;
return NULL;
}
};
int test2()
{
A *b = new A;
return 0;
}
看一下汇编
最终执行的结果
如果我的代码这样写
class A
{
public:
A(){ cout << "构造" << endl; }
int a;
void * operator new(size_t size)
{
cout << "dong" << endl;
return (void *)1;
}
};
int test2()
{
A *b = new A;
return 0;
}
结果就是
为啥是这样应该都能明白吧!!
验证5:为啥说功能和malloc一模一样
class A
{
public:
A(){ cout << "构造" << endl; }
int a;
void * operator new(size_t size)
{
cout << "dong" << endl;
return (void *)1;
}
};
int test2()
{
A *b = (A *)operator new (12);
A *c = (A *)malloc(12);
}
看一下源码 VC/crt/src/newop.cpp
void *__CRTDECL operator new(size_t count) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(count)) == 0)
if (_callnewh(count) == 0)
{ // report no memory
_STD _Xbad_alloc();
}
return (p);
}
其实底层就是调用的malloc
有人会奇怪我不是重载了operator new()么?为啥不打印?
因为我们调用的是全局operator new()啊,C++编译器在全局给我们默认创建了一个
那我们怎么调用自己类中的operator new()呢?没有对象我们能调用类中的函数么?
1.没有类对象我们是可以调用类中部分函数的。
2.更何况重载了operator new()编译器会自动帮我们把这个函数改为static的,也就是静态的。
所以不管是哪一方面都是可以调用的
然后我们看一看 定位new
下面 new A 就等价于上面两句话
注意上面这幅图我没有重载operator new(),因为如果重载了,定位new的时候会发生参数不匹配问题
如果你实在想调用自定义的operator new()可以这样写
A *p = (A*)operator new(sizeof(A));
A *a = new (p) A;
new的知识还是蛮多的