C+中的自定义异常+; 我一直在尝试为我正在处理的C++库制作一些自定义异常类。这些自定义异常捕获调试所需的额外信息,如文件、行号等,如果测试时由于某种原因未在正确的位置捕获异常。然而,大多数人似乎都建议从STL中的std::exception类继承,我同意这一点,但我想知道,如果使用多重继承从每个(例如std::runtime_error)和自定义异常类继承,可能会更好,如下面的代码所示
另一件事,如何在异常类中复制构造函数和赋值运算符?他们应该被禁用吗C+中的自定义异常+; 我一直在尝试为我正在处理的C++库制作一些自定义异常类。这些自定义异常捕获调试所需的额外信息,如文件、行号等,如果测试时由于某种原因未在正确的位置捕获异常。然而,大多数人似乎都建议从STL中的std::exception类继承,我同意这一点,但我想知道,如果使用多重继承从每个(例如std::runtime_error)和自定义异常类继承,可能会更好,如下面的代码所示,c++,stl,exception,multiple-inheritance,C++,Stl,Exception,Multiple Inheritance,另一件事,如何在异常类中复制构造函数和赋值运算符?他们应该被禁用吗 class Exception{ public: explicit Exception(const char *origin, const char *file, const int line, const char *reason="", const int errno=0) throw();
class Exception{
public:
explicit Exception(const char *origin, const char *file,
const int line, const char *reason="",
const int errno=0) throw();
virtual ~Exception() throw();
virtual const char* PrintException(void) throw();
virtual int GetErrno(void);
protected:
std::string m_origin;
std::string m_file;
int m_line;
std::string m_reason;
int m_errno;
};
class RuntimeError: public virtual std::runtime_error, public Exception{
public:
explicit RuntimeError(const char *origin, const char *file,
const int line, const char *reason="",
const int errno=0) throw();
virtual ~RuntimeError() throw();
};
你应该试试
Boost异常的目的是
简化异常类的设计
层次结构和帮助编写
异常处理和错误报告
代码
它支持任意数据的传输
将数据发送到catch站点,即
由于没有投掷,其他方面很棘手
例外情况的要求(15.5.1)
类型。数据可以添加到任何
异常对象,或者直接在
抛出表达式(15.1),或在
稍后将时间作为异常对象
向上传播调用堆栈
向异常添加数据的能力
对象在传递给之后
投掷很重要,因为通常有些
处理一个问题所需的信息
异常在中不可用
检测到故障的上下文
Boost异常还支持
N2179异常的样式复制
对象,以非侵入方式实现
并自动由
boost::抛出异常函数
我想知道使用多重继承来继承每个派生的std::exception类是否更好
请注意,这是一个问题,因为标准库中的异常非虚拟地彼此派生。如果引入多重继承,则在没有虚拟继承的情况下会得到可怕的菱形异常层次结构,并且将无法通过std::exception&
捕获派生异常,因为派生异常类包含两个子对象std::exception
,从而使std::exception
成为“不明确的基类”
具体例子:
class my_exception : virtual public std::exception {
// ...
};
class my_runtime_error : virtual public my_exception
, virtual public std::runtime_error {
// ...
};
现在,my_runtime_error
从std::exception
两次间接派生,一次通过std::run_time_error
和一次通过my_exception
。由于前者实际上不是从std::exception
派生的,因此
try {
throw my_runtime_error(/*...*/);
} catch( const std::exception& x) {
// ...
}
不行
编辑:
我想我在Stroustrup的一本书中看到了涉及MI的异常类层次结构的第一个示例,所以我得出结论,一般来说,这是一个好主意。事实上,STD LIB的例外并不是从我认为是失败的事实中派生出来的。p>
当我上次设计异常层次结构时,我非常广泛地使用了MI,但没有从std库的异常类派生。在这个层次结构中,有一些抽象异常类,您定义这些类是为了让用户能够捕获它们,还有相应的实现类,它们是从这些抽象类和实现基类派生的,您实际上会抛出它们。为了简化这一过程,我定义了一些模板,这些模板将完成所有艰苦的工作:
// something.h
class some_class {
private:
DEFINE_TAG(my_error1); // these basically define empty structs that are needed to
DEFINE_TAG(my_error2); // distinguish otherwise identical instances of the exception
DEFINE_TAG(my_error3); // templates from each other (see below)
public:
typedef exc_interface<my_error1> exc_my_error1;
typedef exc_interface<my_error2> exc_my_error2;
typedef exc_interface<my_error3,my_error2> // derives from the latter
exc_my_error3;
some_class(int i);
// ...
};
//something.cpp
namespace {
typedef exc_impl<exc_my_error1> exc_impl_my_error1;
typedef exc_impl<exc_my_error2> exc_impl_my_error2;
typedef exc_impl<exc_my_error3> exc_impl_my_error3;
typedef exc_impl<exc_my_error1,exc_my_error2> // implements both
exc_impl_my_error12;
}
some_class::some_class(int i)
{
if(i < 0)
throw exc_impl_my_error3( EXC_INFO // passes '__FILE__', '__LINE__' etc.
, /* ... */ // more info on error
);
}
//something.h
上课{
私人:
DEFINE_TAG(my_error1);//这些基本上定义了需要的空结构
DEFINE_TAG(my_error2);//区分异常的其他相同实例
定义_标记(my_error3);//相互之间的模板(见下文)
公众:
类型定义exc_接口exc_我的错误1;
类型定义exc_接口exc_我的错误2;
typedef exc_接口//派生自后者
执行我的错误3;
某些_类(inti);
// ...
};
//某物
名称空间{
typedef exc_impl exc_impl_my_error 1;
typedef exc_impl exc_impl_my_error 2;
typedef exc_impl exc_impl_my_error 3;
typedef exc_impl//实现这两个功能
执行我的错误12;
}
some_类::some_类(inti)
{
if(i<0)
抛出exc_impl_my_error 3(exc_INFO//passes'\uu FILE_uuuuuuuuuuuu'、'\uuuuu LINE_uuuuuuuuuuu'等)。
,//*…*///有关错误的详细信息
);
}
现在回过头来看,我认为我可以使
exc_impl
类模板从std::exception
(或std lib exception层次结构中的任何其他类,作为可选模板参数传递),因为它从未从任何其他exc_impl
实例派生。但那时候不需要这样,所以我从来没有想过 你会从中得到什么?为什么不使用单一继承?为什么需要自定义异常和RuntimeError异常?我想使用自定义异常类中的功能,并通过继承各种派生的std::Exception类来维护STL异常层次结构。这样一个catch:try{throw RunTimeException(…);}catch(std::runtime_error&e){…}catch(std::exception&e){…}也可以捕获我的自定义类。但这可能是浪费时间。我也可以尝试{throw RunTimeException(…);}catch(std::exception&e){…},但这样会使识别异常变得更加困难。我不知道自定义异常类时的典型实践是什么?我会说只是从std::runtime_错误(或std::exception)继承。如果你想要一个特殊的治疗,你可以有多个捕手。(特别是在C++中)。更易于使用的代码,如boost::exception
,经过广泛的同行评审和战斗测试。我以前从未使用过boost。我会调查的。谢谢你的帖子。谢谢你的帖子。使用多重继承生成异常类是一种好的做法吗?还是从std::exception类继承更好?但他没有这个问题。你已经走了