由于我正在为Windows和Linux编写代码,因此我遇到了许多问题。 Microsoft Visual C ++没有stdint标头,但为此,我编写了自己的标题。
现在我发现MS C ++的新运算符没有抛出异常,所以我想尽快解决这个问题。我知道我可以在括号中定义带参数的宏,我可以定义一个替换
的宏MyClass x = new MyClass();
与
#ifdef MSC_VER
if(!(MyClass x = new MyClass())
{
throw new std::bad_alloc();
}
#else
MyClass x = new MyClass();
#endif
(或类似的东西),AND在MS C ++和G ++中工作?
或者,如果不可能,则运行代码的批处理文件执行此操作? 我已经变得非常依赖抛出这个异常。
答案 0 :(得分:2)
微软的C ++编译器非常接近100%符合标准,除了一些不起眼的东西。不在新的中抛出异常不是其中之一。
除此之外,你不能编写一个可以检测到该表达式并相应地处理它的宏,除非你想重写new
的所有用法(击败目的)。
答案 1 :(得分:1)
实际上,有一个简单的解决方案:replace operator new,其中一个会导致分配失败。 (链接代码是标准C ++,可能需要对编译器进行调整。您可以将malloc用于allocate_from_some_other_source并为deallocate_from_some_other_source使用。)
(这些替换确实需要更改调用代码,因为C ++语法的结构是不可避免的。但是,它们被编写为需要最小的更改才能用作逻辑插入式替换。真正的解决方案是从过去7年左右升级到MSVC版本。听起来你正在使用的MSVC6实际上是在1998年C ++标准之前发布的。)
解决一般情况很难,但这是一个近似值:
struct Thrower { // needs a better name
void* p;
Thrower(void* p) : p(p) {
if (!p) throw std::bad_alloc();
}
~Thrower() {
if (std::uncaught_exception()) operator delete(p);
// this is true when the object's ctor throws
}
operator void*() const { return p; }
};
int main() {
int* p = new (Thrower(operator new(sizeof(int))) int(42);
// int is a placeholder type, but shows you can still pass ctor parameters
// with a macro becomes:
#define MYNEW(T) new (Thrower(operator new(sizeof(T))) T
int* p = MYNEW(int)(42);
}
对于已知参数,您可以避免使用宏并保持简单:
template<class T>
T* my_new() {
T* p = new T();
if (!p) throw std::bad_alloc();
return p;
}
template<class T>
T* my_new(T const& value) {
T* p = new T(value);
if (!p) throw std::bad_alloc();
return p;
}
int main() {
int* p = my_new<int>();
int* p2 = my_new<int>(*p);
}
答案 2 :(得分:1)
最简单的替代方法是编写自己的operator new
实现,覆盖编译器的默认实现(如果您的MSVC版本支持它)。罗杰在他的链接答案中也提出了这一点。
以下程序说明了这种尝试。 operator new
使用malloc
和free
从堆中分配内存。如果您正在为G ++和MSVC进行条件编译,您还可以使用HeapAlloc
和HeapFree
代替malloc
和free
来实现更加面向WinAPI的方法。
#include <iostream>
#include <cstdlib>
void *operator new(unsigned int size) throw (std::bad_alloc) {
void *ptr = malloc(size);
if (!ptr)
throw std::bad_alloc();
return ptr;
}
void operator delete(void *ptr) throw () {
free(ptr);
}
// Sample code to test the implementation.
int main(int argc, char **argv) {
int *values[10];
for (int i = 0; i < 10; ++i)
values[i] = new int(i);
for (int i = 0; i < 10; ++i)
std::cout << *values[i] << std::endl;
for (int i = 0; i < 10; ++i)
delete values[i];
return 0;
}