解决方法
新表达和分配
>代码包含一个提供type-id的new-expression.
>编译器将查看类型是否使用分配函数重载operator new.
>如果它发现运算符新分配函数的重载,则使用赋予new和sizeof(TypeId)作为其第一个参数的参数调用该函数:
样品:
new (a,b,c) TypeId; // the function called by the compiler has to have the following signature: operator new(std::size_t size,TypeOfA a,TypeOfB b,TypeOf C c);
>如果operator new无法分配存储空间,它可以调用new_handler,并希望它能够生成.如果仍然没有足够的位置,new必须抛出std :: bad_alloc或从中派生.一个具有throw()(无抛出保证)的分配器,在这种情况下它应该返回一个空指针.
> C运行时环境将创建由分配函数返回的内存中由type-id指定的类型的对象.
>不要扔新的.这需要一个nothrow_t作为第二个参数.如下所示的表单的新表达式将调用仅使用std :: size_t和nothrow_t的分配函数:
例:
new (std::nothrow) TypeId;
>安置新.这将void *指针作为第一个参数,而不是返回新分配的内存地址,它返回该参数.它用于在给定地址创建对象.标准容器使用它来预分配空间,但稍后只在需要时创建对象.
码:
// the following function is defined implicitly in the standard library void * operator(std::size_t size,void * ptr) throw() { return ptr; }
如果分配函数返回存储,并且运行时创建的对象的构造函数抛出,则会自动调用operator delete.如果使用了一种新的形式,它需要额外的参数,比如
new (a,c) TypeId;
然后调用那些参数的运算符delete.只有在删除完成时才调用该运算符删除版本,因为对象的构造函数确实抛出了.如果你自己调用delete,那么编译器将使用普通的operator delete函数,只取一个void *指针:
int * a = new int; => void * operator new(std::size_t size) throw(std::bad_alloc); delete a; => void operator delete(void * ptr) throw(); TypeWhosCtorThrows * a = new ("argument") TypeWhosCtorThrows; => void * operator new(std::size_t size,char const* arg1) throw(std::bad_alloc); => void operator delete(void * ptr,char const* arg1) throw(); TypeWhosCtorDoesntThrow * a = new ("argument") TypeWhosCtorDoesntThrow; => void * operator new(std::size_t size,char const* arg1) throw(std::bad_alloc); delete a; => void operator delete(void * ptr) throw();
new-expression和数组
如果你这样做
new (possible_arguments) TypeId[N];
编译器使用operator new []函数而不是plain operator new.操作符可以传递第一个不完全是sizeof的参数(TypeId)* N:编译器可以添加一些空间来存储创建的对象数(为了能够调用析构函数而需要).标准就是这样说的:
> new T [5]导致调用operator new [](sizeof(T)* 5 x),和> new(2,f)T [5]导致运算符new []的调用(sizeof(T)* 5 y,2,f).