请看下面的代码:
#include<iostream>
#include<stdlib.h>
#include<new>
using namespace std;
class ex
{
int x;
public:
ex():ex(0){}
ex(int x):x(x)
{
//cout<<"\nConstructor";
}
void *operator new(size_t siz)
{
void *p;
cout<<"\nOverloaded new operator normal version";
p=malloc(siz);
if(p==NULL)
{
bad_alloc ba;
throw ba;
}
else
return p;
}
void operator delete(void *p,size_t sz)
{
cout<<"\nOverloaded delete normal version:"<<sz;
free(p);
}
void *operator new(size_t siz,const nothrow_t &tag)
{
void *p;
cout<<"\nOverloaded new operator nothrow version";
p=malloc(siz);
if(p==NULL)
{
return 0;
}
else
return p;
}
void operator delete(void *p,const nothrow_t &tag)
{
cout<<"\nOverloaded delete nothrow version";
free(p);
}
void *operator new[](size_t siz)
{
void *p;
cout<<"\nOverloaded new operator normal version in array";
p=malloc(siz);
if(p==NULL)
{
bad_alloc ba;
throw ba;
}
else
return p;
}
void operator delete[](void *p,size_t sz)
{
cout<<"\nOverloaded delete normal version in array:"<<sz;
free(p);
}
void *operator new[](size_t siz,const nothrow_t &tag)
{
void *p;
cout<<"\nOverloaded new operator nothrow version in array";
p=malloc(siz);
if(p==NULL)
{
return 0;
}
else
return p;
}
void operator delete[](void *p,const nothrow_t &tag)
{
cout<<"\nOverloaded delete nothrow version in array";
free(p);
}
};
int main()
{
ex *pt;
pt=new ex;
delete pt;
pt=new ex[10];
delete[] pt;
pt=new(nothrow) ex;
delete pt;
pt=new(nothrow) ex[10];
delete[] pt;
}
Run Code Online (Sandbox Code Playgroud)
上述代码的输出:
Overloaded new operator normal version
Overloaded delete normal version:4
Overloaded new operator normal version in array
Overloaded delete normal version in array:44
Overloaded new operator nothrow version
Overloaded delete normal version:4
Overloaded new operator nothrow version in array
Overloaded delete normal version in array:44
Process returned 0 (0x0) execution time : 0.724 s
Press any key to continue.
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1)为什么不调用delete的nothrow版本。
2)我可以在删除的无抛出版本中使用大小参数吗?喜欢
void operator delete[](void *p,const nothrow_t &tag,size_t sz);
or
void operator delete(void *p,const nothrow_t &tag,size_t sz);
Run Code Online (Sandbox Code Playgroud)
3)nothrow版本的delete有什么用。
4)我在 new 和 new[] 版本、delete 和 delete[] 版本中使用了相同的代码,但一个是普通变量,另一个是数组变量,这是怎么回事?
5)编译器给出警告:'operator new'不能返回NULL,除非它被声明为'throw()'(或者-fcheck-new有效)如何克服这个问题?
newC++bad_alloc失败时会抛出异常,new除非您显式调用new(std::nothrow).
这不受用户是否重载operator new问题的影响。
因此,当您调用new而不传递时std::nothrow,您将不会达到 nothrot 版本。即使你超载了。
new(nothrow)请注意,您的nothrow版本确实会抛出异常,这不是正确的方法。它应该看起来像:
void* operator new(size_t size, const nothrow_t& tag) noexcept
{
void* p = malloc(size);
return p; // don't throw from the nothrow version of new
}
Run Code Online (Sandbox Code Playgroud)
然而,这不会改变所解释的行为:要达到您必须显式调用nothrow它的版本new,正如您在代码中确实看到的那样。
有些编译器允许“禁用”异常,例如--exceptionsgcc 中的标志。这取决于编译器,但在大多数情况下,即使不是全部 - 抛开旧版本的 MSVC - 禁用异常不会导致异常不被抛出,而只会使编译器假设它们不会被抛出,并且调用仍然会new抛出如果失败了。
海湾合作委员会示例:http ://coliru.stacked-crooked.com/a/daa465731e56c681
相关SO问题:
也可以很好地阅读:
操作delete员永远不应该抛出异常。它的两个版本,普通版nothrow和普通版(非无抛出)。
nothrow那么版本有什么用呢operator delete?
如果new调用分配对象,内存已成功分配,但该对象的构造函数抛出异常,则 new 操作将失败,并传播构造函数抛出的异常。但在此之前需要释放获得的内存。这是通过呼叫delete操作员自动完成的。如果new刚刚失败的是那个nothrow版本,那么delete要调用的操作员就是那个nothrow版本,否则就是正常的操作员。请注意,两个版本的delete运算符都不会也不应该抛出异常。另请注意,您不能自行调用运营商nothrow的版本!delete但您可以创建一个调用它的场景。
例子:
struct A {
A() {
throw "bahh";
}
};
void operator delete(void* ptr) noexcept {
std::cout << "normal delete" << std::endl;
free(ptr);
}
void operator delete(void* ptr, const std::nothrow_t&) noexcept {
std::cout << "nothrow delete" << std::endl;
free(ptr);
}
int main() {
std::cout << "calling new A" << std::endl;
try {
new A(); // prints: normal delete
}
catch(const char* s) {
std::cout << s << std::endl; // bahh
}
std::cout << "calling new(std::nothrow) A" << std::endl;
try {
new(std::nothrow) A(); // prints: nothrow delete
}
catch(const char* s) {
std::cout << s << std::endl; // bahh
}
}
Run Code Online (Sandbox Code Playgroud)
代码:http ://coliru.stacked-crooked.com/a/7be9ce12d251b033
看:
| 归档时间: |
|
| 查看次数: |
1512 次 |
| 最近记录: |