std :: exception子类,字符串成员变量

时间:2011-12-23 16:01:11

标签: c++ string exception

以下代码可以正常使用:

#include <exception>

using namespace std;

class FileException : public exception { // error occurs here
    int _error;
    // string _error; <-- this would cause the error
public:
    FileException(int error);
    // FileException(string error);
    const char* what() const throw();
};

但是只要我将_error的类型更改为字符串,就会发生以下编译错误:

  

覆盖函数的异常规范比基本版本更宽松

3 个答案:

答案 0 :(得分:23)

std::string的析构函数 not no-throw,这导致FileException 的隐式析构函数不是 no-throw。但是std::exception的析构函数是无抛出的,因此存在编译器错误。

你可以声明一个明确的无抛出析构函数:

virtual ~FileException() throw() {}

或者只是从std::runtime_error而不是std::exception继承而来,std::string有一个带{{1}}输入的构造函数。

答案 1 :(得分:6)

简化:

// Derive from std::runtime_error rather than std::exception
// std::runtime_error (unlike std::exception) accepts a string as an argument that will
// be used as the error message.
//
// Note: Some versions of MSVC have a non standard std::exception that accepts a string
//       Do not rely on this.
class FileException : public std::runtime_error
{
public:
    // Pass error msg by const reference.
    FileException(std::string const& error)
        // Pass the error to the standard exception
        : std::runtime_error(error)
    {}
    // what() is defined in std::runtime_error to do what is correct
};

答案 2 :(得分:0)

我赞成上述方法,

g ++ 似乎抱怨如果 默认构造函数不存在。

以下添加使事情有效:

using namespace std;

class MyException : public runtime_error {
public:
  /* add the following line: */
  MyException() : runtime_error("MyException") { } // default constructor

  MyException( string const& error ) : runtime_error(error) { }  // ctor w/string
};

另外,可以轻松创建例外列表:

MyException FileNotFound ( "File Not Found" );
MyException ReadOnly     ( "ReadOnly"       );
MyException Unkown       ( "Unknown"        );

...
throw FileNotFound;
...

在捕获这些异常时,如果您不需要特异性,则一般性地捕获它们:

catch( runtime_error re) {  cout << "Runtime Error: " << re.what() << endl;  ... }

由于所有MyExceptions都是从runtime_error开始的,因此它会捕获所有这些内容 您不会错过系统中的任何其他运行时错误。

catch( exception e) {  cout << "exception: " << e.what() << endl;  ... }

抓住他们所有人。

在C ++中,你也可以抛出并捕获任何类型(int,booleans,pointers等)。它有时更简单 在函数块中抛出/捕获字符串或int。

多个类应该只抛出并捕获代码库标准异常及其子类(并且都以相同的方式),但主要是为了一致性和维护,还因为c ++编译器知道如何优化异常机制和链接它们,可以生成有关它们的智能警告和错误,从而简化调试。

“错误:”0x137F“适用于IBM员工,而不是”今年项目中的第三个人“......