我只是一个初出茅庐的程序员,至少尝试编写比最佳情况更多的程序。到目前为止,我一直在阅读 Herb Sutter 的“Exceptional C++”,并且已经阅读了三次异常安全章节。但是,除了他提出的示例(堆栈)之外,我不确定何时应该争取异常安全与速度,以及何时这样做很愚蠢。
例如,我目前的家庭作业项目是一个双向链表。因为我已经编写了其中的几个,所以我想花时间来了解一些更深层次的概念,比如 ES。
这是我的弹出式功能:
void List::pop_front()
{
if(!head_)
throw std::length_error("Pop front: List is empty.\n");
else
{
ListElem *temp = head_;
head_ = head_->next;
head_->prev = 0;
delete temp;
--size_;
}
}
我对此感到有些困惑。
1)当列表失败时我真的应该抛出错误吗?我不应该简单地什么都不做并返回,而不是强迫列表的用户执行 try {] catch() {} 语句(这也很慢)。
2)有多个错误类(加上我老师要求我们在课堂上实现的 ListException)。这样的事情真的需要自定义错误类吗?是否有关于何时使用特定异常类的一般指南?(例如,范围、长度和边界听起来都一样)
3) 我知道在所有引发异常的代码完成之前,我不应该更改程序状态。这就是我最后减小 size_ 的原因。在这个简单的例子中这真的有必要吗?我知道删除不能扔。head_->prev 在分配为 0 时是否有可能抛出?(头是第一个节点)
我的 push_back 函数:
void List::push_back(const T& data)
{
if(!tail_)
{
tail_ = new ListElem(data, 0, 0);
head_ = tail_;
}
else
{
tail_->next = new ListElem(data, 0, tail_);
tail_ = tail_->next;
}
++size_;
}
1) 我经常听说C++ 程序中的任何事情都可能失败。测试 ListElem 的构造函数是否失败(或 tail_ 在new
ing 期间)是否现实?
2)是否有必要测试数据的类型(目前很简单typedef int T
,直到我将所有内容都模板化)以确保该类型对于结构是可行的?
我意识到这些都是过于简单的例子,但我目前只是对何时应该真正练习良好的 ES 以及何时不应该感到困惑。