c – 如何正确地抛出一个不仅仅是一个构造函数的异常?

我有一个异常类,我想在其上放置更多的信息.我可以创建Exception对象,调用其中的一些函数,然后将其抛出,而不会复制它的任何副本?

我发现唯一的方法是抛出一个指向该对象的指针:

class Exception : public std::runtime_error
{
public:
    Exception(const std::string& msg) : std::runtime_error(msg) {}
    void set_line(int line) {line_ = line;}
    int get_line() const {return line_;}
private:
    int line_ = 0;
};

std::unique_ptr<Exception> e(new Exception("message"));
e->set_line(__LINE__);
throw e;
...
catch (std::unique_ptr<Exception>& e) {...}

但是通常可以避免指针抛出异常,还有其他方法吗?

还可以通过构造函数设置所有选项,但是如果将更多的字段添加到类中,并且要对要设置的字段进行细粒度控制,则可以快速变为不可扩展:

throw Exception("message"); // or:
throw Exception("message",__LINE__); // or:
throw Exception("message",__FILE__); // or:
throw Exception("message",__LINE__,__FILE__); // etc.

解决方法

使用std :: move怎么办?
Exception e("message");
e.set_line(__LINE__);
throw std::move(e);

或者,您可以创建如下的Java-esque构建器:

class ExceptionBuilder;

class Exception : public std::runtime_error
{
public:
    static ExceptionBuilder create(const std::string &msg);

    int get_line() const {return line_;}
    const std::string& get_file() const { return file_; }
private:
    // Constructor is private so that the builder must be used.
    Exception(const std::string& msg) : std::runtime_error(msg) {}

    int line_ = 0;
    std::string file_;

    // Give builder class access to the exception internals.
    friend class ExceptionBuilder;
};

// Exception builder.
class ExceptionBuilder
{
public:
    ExceptionBuilder& with_line(const int line) { e_.line_ = line; return *this; }
    ExceptionBuilder& with_file(const std::string &file) { e_.file_ = file; return *this; }
    Exception finalize() { return std::move(e_); }
private:
    // Make constructors private so that ExceptionBuilder cannot be instantiated by the user.
    ExceptionBuilder(const std::string& msg) : e_(msg) { }
    ExceptionBuilder(const ExceptionBuilder &) = default;
    ExceptionBuilder(ExceptionBuilder &&) = default;

    // Exception class can create ExceptionBuilders.
    friend class Exception;

    Exception e_;
};

inline ExceptionBuilder Exception::create(const std::string &msg)
{
    return ExceptionBuilder(msg);
}

这样使用:

throw Exception::create("TEST")
    .with_line(__LINE__)
    .with_file(__FILE__)
    .finalize();

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...