查看<new>中对new的声明.
void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t, const std::nothrow_t&) throw();
如果使用,new T () 程序,调用 void* operator new(std::size_t) throw (std::bad_alloc); 在内存不足的情况下,将抛出bad_alloc异常.
如果使用,new (nothrow) T () 程序,调用 void* operator new(std::size_t, const std::nothrow_t&) throw(); 拥有空异常修饰符,不允许抛出任何异常,其定义中,如果内存不足返回值为0.
C++11标准中:
throw() 已经被弃用,而使用noexcept “异常声明” 替代。
void f() noexcept {...} // 函数不抛出任何异常,如果函数体出现异常,程序直接中断
void f() noexcept(true){...} // 同上
void f() noexcept(false) {...} // 函数允许抛出异常,如果函数提出现异常,将向上抛出异常
C++11中取消了:void f() throw (int ,double) {...} 这种指定函数抛出异常类型的方式,以void f() noexcept(false) {...} 取代。
但,目前看来,支持C++11标准的编译器实际上也没有准训以上标准,任然使用以前的格式。更多可以参见gnu 4.8.2源码
/*
* File: Player.h
* Author: Vicky.H
* Email: eclipser@163.com
*
* Created on 2014年1月21日, 下午7:17
*/
#ifndef PLAYER_H
#define PLAYER_H
#define NDEBUG
#if defined(__cplusplus) && (__cplusplus >= 201103) // C++11
#ifndef NDEBUG
#define VNOECEPT noexcept(true) // debug版本,不允许析构函数等抛出异常
#else
#define VNOECEPT noexcept(false) // release版本,允许析构函数等抛出异常
#endif
#else
#ifndef NDEBUG
#define VNOECEPT throw() // debug版本,不允许析构函数等抛出异常
#else
#define VNOECEPT // release版本,允许析构函数等抛出异常
#endif
#endif
class Player {
public:
Player();
Player(const Player& orig);
virtual ~Player() VNOECEPT /**一般析构函数都不允许抛出异常,*/;
private:
};
#endif /* PLAYER_H */
/*
* File: Player.cpp
* Author: Vicky.H
* Email: eclipser@163.com
*
* Created on 2014年1月21日, 下午7:17
*/
#include "Player.h"
Player::Player() {
}
Player::Player(const Player& orig) {
}
Player::~Player() VNOECEPT {
throw "~Player() not allow throw exception, but throwed";
}
/*
* File: main7.cpp
* Author: Vicky.H
* Email: eclipser@163.com
*/
#include <iostream>
#include <new>
#include "Player.h"
void f1() throw () {
std::cout << "f1()" << std::endl;
}
// C++11标准
void f2() noexcept { // 不抛出异常 noexcept = noexcept(true)
std::cout << "f2()" << std::endl;
}
template <typename T>
const T& max(const T& o1, const T& o2) noexcept(false) { // 要抛出异常
return o1 > o2 ? o1 : o2;
}
template<>
const int& max(const int& o1, const int& o2) noexcept(false){ // noexcept(true) ERROR 当模版设置为要抛出异常,儿模版的范例却不抛出异常将导致错误
return o1 < o2 ? o1 : o2;
}
/*
*
*/
int main(void) {
f1();
f2();
std::cout << "\n---------------------------" << std::endl;
std::cout << max(1.0, 2.0) << std::endl;
std::cout << max(1, 2) << std::endl;
std::cout << "\n---------------------------" << std::endl;
try {
Player* p = new Player();
delete p;
} catch (...) {
std::cout << "except happen" << std::endl;
}
return 0;
}
#include <new>
#include <iostream> // for std::cerr
#include <cstdlib> // for std::exit()
Task * ptask = new (std::nothrow) Task;
if (!ptask)
{
std::cerr<<"allocation failure!";
std::exit(1);
}
//... allocation succeeded; continue normally
内存分配失败是非常普通的,它们通常在植入性和不支持异常的可移动的器件中发生更频繁。因此,应用程序开发者在这个环境中使用nothrow new来替代普通的new是非常安全的。