我有一个C++程序,其中new
操作符重载。问题是,如果我在new
操作符中的分配失败,我仍然在调用构造函数。我知道我可以通过抛出std::bad_alloc
来避免这种情况,但我不想这样做。
如何在重载的new
操作符中失败,仍然不调用构造函数?本质上,我想实现类似于new (std::nothrow)
的东西。
这里有一个例子来说明我的意思。注意,我正在测试的系统没有内存保护。所以访问并没有做什么
示例1:重载的新运算符
#include <stdio.h>
#include <stdlib.h>
#include <memory>
class Test {
public:
Test(void) {
printf("Test constructor\n");
}
void print(void) {
printf("this: %p\n", this);
}
void* operator new(size_t size, unsigned int extra) {
void* ptr = malloc(size + extra);
ptr = NULL; // For testing purposes
if (ptr == NULL) {
// ?
}
return ptr;
}
};
int main(void) {
Test* t = new (1) Test;
t->print();
printf("t: %p\n", t);
return 0;
}
这样做的结果是:
$ ./a.out
Test constructor
this: 00000000
t: 00000000
显然,当new
失败时,解析器正在被调用。
示例2:使用new的大型类声明(std::new)
#include <stdio.h>
#include <stdlib.h>
#include <memory>
class Test {
int x0[0x0fffffff];
int x1[0x0fffffff];
int x2[0x0fffffff];
int x3[0x0fffffff];
int x4[0x0fffffff];
int x5[0x0fffffff];
int x6[0x0fffffff];
int x7[0x0fffffff];
int x8[0x0fffffff];
int x9[0x0fffffff];
int xa[0x0fffffff];
int xb[0x0fffffff];
int xc[0x0fffffff];
int xd[0x0fffffff];
int xe[0x0fffffff];
int xf[0x0fffffff];
public:
Test(void) {
printf("Test constructor\n");
}
void print(void) {
printf("this: %p\n", this);
}
};
int main(void) {
Test* t = new (std::nothrow) Test;
t->print();
printf("t: %p\n", t);
return 0;
}
这样做的结果是:
this: 00000000
t: 00000000
显然,构造器是,而不是,在new
失败时被调用。
那么,如何在重载的new (std::nothrow)
操作符中实现new
的功能呢?
发布于 2013-03-08 10:43:50
编译器在调用operator new
之后,在调用析构函数之前是否检查空指针,取决于分配程序函数是否具有无抛出的异常规范。如果没有,编译器假设如果没有可用内存,operator new
将抛出。否则,它假设operator new
将返回一个空指针。就您的情况而言,您的operator new
应该是:
void* operator new( size_t size, unsigned int extra ) throw()
{
//...
}
或者,如果您可以指望C++11支持:
void* operator new( size_t size, unsigned int extra) noexcept
{
}
https://stackoverflow.com/questions/15291971
复制相似问题