我正在尝试为std::vector
创建一个容器类,以教会自己更多地了解模板,重载操作符和管理异常。std ::向量segfaulting而不是抛出异常
目前,我只是定义了基本操作。我有一个下面列出的模板类;我已将+=
和[]
运算符重载为push_back
vector
和T
,并分别直接访问该向量的元素。这按预期工作。
+=
运算符做它应该做的事情,并试图在超出范围的元素上使用运算符[]
将按预期抛出异常。
这里是原型类和实施,因为它目前为:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
template <class T>
class Inventory
{
public:
void operator += (const T& b) { backpack.push_back(b); }
T operator [] (const unsigned& b)
{
if (backpack.empty() || backpack.size() < b)
throw string("Out of Range");
return backpack[b];
}
void operator -= (const unsigned& b)
{
if (backpack.empty() || backpack.size() < b)
throw string("No such element exists.");
backpack.erase(backpack.begin() + b);
}
private:
vector<int> backpack;
};
int main()
{
Inventory<int> pack;
pack += 2;
pack += 4;
try
{
cout << "It was " << pack[0] << endl;
cout << "It was " << pack[1] << endl;
pack -= 0;
cout << "It is now " << pack[0] << endl;
//pack -= 1; // Segfaults?
}
catch (string e)
{
cout << "Error: " << e << endl;
}
}
的问题是与运营商-=
,打算在右手侧指示的位置来消除的元素。当我停留在矢量的边界内时,它会按预期工作;但是,如果我指定要擦除的越界数,我不会收到例外;我得到一个seg-fault。我试图通过添加额外的打印命令来确定段错误的确切点:
void operator -= (const unsigned& b)
{
cout << "In Overload!\n";
if (backpack.empty() || backpack.size() < b)
{
cout << "Exception!\n";
throw string("No such element exists.");
}
backpack.erase(backpack.begin() + b);
}
“异常!”线路永远不会到达。程序在达到该点之前出错,尽管我应该评估未定义的行为。我相信我错过了理解这个过程如何工作的关键组件。有没有一种方法我应该写这个,所以它可以抛出而不是过错?
在Linux x64体系结构上使用g++ -std=c++17 -Wall -Wextra -pedantic
编译。
为什么不简单地使用'std :: vector :: at()'而不是自己写一个无效索引的测试呢? 'vector :: at()'保证会抛出一个'out_of_range'异常。 – PaulMcKenzie
“这个”例外!“cout永远不会到达,程序在达到该点之前就会出错” - 您怎么知道程序将会到达那个点?也许它去了,叫'backpack.erase'。 – immibis
@PaulMcKenzie也许这是一个编码练习。 – immibis