有时候,我们会在某些地方看到new operator/delete operator与operator new/operator delete这两组相似的组合,对于见过后者的人,可能会觉得这两者本就是同样的东西,只是前者写错了而已。其实不然,两者确实是截然不同的东西。
new operator/delete operator,其实就是我们常用来动态分配空间的new和delete操作符,operator也有运算符的意思,注意new和delete是运算符!而operator new/operator delete,它们不是运算符,而是两个函数,同样用以分配空间。此时,或许有人会有疑问了,既然是相同的功能,定义两组,是不是做无用功了?答案是否定的,这不是做无用功!下面我们来看一段代码及两次运行结果,来分析分析两者异同:
1 class Test 2 { 3 private: 4 5 public: 6 Test() { cout << "Constructor of Test!" << endl; } 7 ~Test() { cout << "Destructor of Test!" << endl; } 8 }; 9 10 int main(int argc, char argv[]) 11 { 12 //Test *test = (Test*)operator new(sizeof(Test)); 13 //cout << test << endl; 14 //operator delete(test); 15 Test *test = new Test(); 16 cout << test << endl; 17 delete test; 18 19 return 0; 20 }
未注释段是运用new,delete运算符分配空间,注释段则是调用operator new/operator delete函数进行分配空间。我们可以很明显地从代码及运行结果中发现几个问题:
1.为何调用operator new/operator delete时,Test类的构造函数、析构函数均未被调用,而使用new/delete运算符则调用了?
2.为何调用operator new/operator delete得到空间地址后要进行强制转换,而使用new/delete运算符则不需要?
这就是new/delete运算符与operator new/operator delete函数的区别了。虽然同样是用来分配空间的,但new/delete运算符会对相应的类构造函数、析构函数进行调用,而operator new/operator delete函数则不会,它只单纯的分配一块空间;再有,new运算符返回的是一个该类对象的指针,而operator new函数则返回一个void*类型,因此需要一步强制转换的过程。
提到两者区别,有几点需要提出:
1.new operator/delete operator不可且不应该被重载,这是C++标准要求的;
2.operator new可以被重载,但返回值类型必须为void*(operator delete同样可被重载);
3.operator new重载时,第一个参数必须为表达分配空间的大小(单位为字节),为size_t类型;
4.operator new重载时,满足第三个条件,则可以带其他参数。
PS:最后再提一点,动态分配的空间必须手动释放,C++不具备垃圾回收机制,所以不能放任动态分配的空间不管。用了new就必须用delete,用了operator new就必须用operator delete(new[], operator new[]同理)。operator new分配的空间不能用C库中的free释放,两者具有不同的内存使用登记方式。