今天在看stl源码的同事突然发来一个new表达式
1 template<class _T1, class _T2> 2 3 inline void _Construct(_T1* __p, cosnt _T2& __value) 4 5 { 6 7 new ((void*)__P) _T1(__value); 8 9 }
一下自己迷糊了~~ 这种new的用法还是第一次见,正好比较闲,就查了一下,在百度上看了几篇博文后,大概有了些了解
new其实有三种用法~
1. 当new是运算符的时候
2. 当new是函数的时候
3. 当new作为 placement new 的时候
分别介绍一下用法:
1. 这种使我们最常见的用法
A* a = new A() ; //这里,new不止申请了A那么大的内存,还调用了A的构造函数,将申请的内存用A的构造函数初始化
int* b = new int; //这里申请了一个size(int)大小的内存
int* c = new int[10]; //申请了一个size(int)*10的内存
2. new作为函数
实际上这里‘new’也只是一个运算符,而不是函数名,这个函数是跟重载运算符+的那类函数是一样的~~ 一个类在被第一种new操作的时候,内部做了两件事:
a. 调用系统的operator new函数申请内存
b. 调用类本身的构造函数,在内存空间上做初始化
类是可以重载这个operator new的
1 class A 2 { 3 public: 4 A() 5 { 6 cout<<"A default construct called"<<endl; 7 this->value = 5; 8 } 9 A(B b) 10 { 11 this->value = b.getValue(); 12 } 13 14 int getValue() 15 { 16 return this->value; 17 } 18 19 void * operator new(size_t size = 8) 20 { 21 cout<<"A self defined new called"<<endl; 22 return malloc(size); 23 } 24 private: 25 int value; 26 };
对于类A,如果我们调用
A a = new A();
会分别调用 A::operator new和A::A()两个函数
3. new作为placement new 就是今天碰到的这个new,它允许在已经申请的内存上分配一个对象
调试代码如下:
1 #include <iostream> 2 3 4 using namespace std; 5 6 class B 7 { 8 public: 9 B(int num) 10 { 11 this->value = num; 12 } 13 int getValue() 14 { 15 return this->value; 16 } 17 private: 18 int value; 19 }; 20 21 class A 22 { 23 public: 24 A() 25 { 26 cout<<"A default construct called"<<endl; 27 this->value = 5; 28 } 29 A(B b) 30 { 31 this->value = b.getValue(); 32 } 33 34 int getValue() 35 { 36 return this->value; 37 } 38 39 void * operator new(size_t size = 8) 40 { 41 cout<<"A self defined new called"<<endl; 42 return malloc(size); 43 //return (void*)0; 44 } 45 private: 46 int value; 47 }; 48 49 50 int main() 51 { 52 B b = B(10); //初始化一个类B,这个B是配角,忽略 53 A *p = new A(); //用第一种new,申请内存并初始化一个A, 54 //A *p; 55 cout<<p<<endl; 56 cout<<p->getValue()<<endl; 57 ::new ((void*)p) A(b); //使用A的参数为B的构造函数,重新在p那块内存上重新初始化 58 cout<<p<<endl; 59 cout<<p->getValue()<<endl; 60 66 return 0; 67 }
至此,大概知道了c++ 中new的用法,以前知道的太浅显了。。。不过也可能,以后会发现现在写的这个也是错误的,欢迎各位拍砖~~
备忘:
1. 第二种new可以用于对内存比较敏感的应用,比如,保证类的内存来自于自定义的内存池~~
2. 第一种new的功能 = 第二种new+ 第三种new