我创建了自己的vector类,其行为有点像通常的std :: vector(我需要为此赋值执行此操作)。现在我想确保如果有人试图在这个向量类中写入超出其可访问内存范围的内容,则会出错并终止该程序。
我的尝试:
template<typename T>
class vector
{
private:
T *elements;
int sz;
public:
// vector functions etc. //
struct out_of_range
{
string s;
out_of_range(string b) : s{b} {cerr << "error: " << s << endl;}
};
};
所以现在在我的矢量成员函数中可能会遇到超出范围的错误,我抛出这个类。例如,在我的运算符重载[]中,我有一个这样的检查:
if(i < 0 || sz <= i) throw out_of_range("index out of range");
现在这样可行,并使用以下消息终止程序:
错误:索引超出范围 抛出'vector :: out_of_range'的实例后终止调用 中止(核心倾销)
我的问题是这是否是正确的方法。我是否允许从像我这样的函数中进行cerr并且我可以简单地抛出此函数而不捕获它?据我所知,没有捕捉调用终止()对吗?这是不好的编码实践吗?
我希望我没有让你们困惑,我的问题在某种程度上是可以理解的。感谢您提前提供任何帮助:)
编辑:对不起我应该提到,我不允许使用我自己没有创建的任何类,除了一些基本的类,比如std :: string和基本的输入和输出。
答案 0 :(得分:0)
不同的Java,在C ++中,您可以使用非异常特定的元素在throw语句中使用。所以,你的struct适合用作表达式参数来抛出异常,就像(就像int数一样)。
但是,由于您使用OOP方法编写程序,因此您还应该为您的例外应用类替代方法:
#include <iostream>
#include <exception>
using namespace std;
class myexception: public exception {
virtual const char* what() const throw() {
return "My exception happened";
}
} myex;
int main () {
try {
throw myex;
} catch (exception& e) {
cout << e.what() << '\n';
}
return 0;
}
取自here。
第一印象是两种选择都是等价的。基于struct的类的好处是,通过类,您可以提取面向对象方法提供的重用,扩展,封装等优点,这在编写更复杂,更庞大和更长寿命的系统时非常有用。