我一直在阅读swap()
操作,例如:
template<class T>
void swap (T &a, T &b)
{
T temp (a);
a = b;
b = temp;
}
当我们处理异常安全时,这是有问题的。
怎么了
此外,我们该如何解决呢?
最佳答案
在一般的实现中,假设T
的任何操作都可以throw
,则您不能提供强大的异常保证,这意味着在发生异常事件时,将状态完全保留在操作之前。即使对T
的每个操作都提供了强大的异常保证:
template<class T>
void swap (T &a, T &b)
{
T temp (a); // [1]
a = b; // [2]
b = temp; // [3]
}
如果抛出[1],则输入保持不变,这很好。如果抛出[2],并假设有强异常保证,则这些值仍保持不变,这很好。但是,如果抛出的是[3],则
a
已被修改,这意味着在异常传播到堆栈之后,调用方将处于既不是原始状态也不是最终状态的状态。编辑:此外,我们如何解决呢?
没有通用的解决方案。但是在大多数情况下,您可以为您的类型提供异常安全的
swap
操作。考虑一个vector<T>
,它通过使用三个指针(begin
,end
,capacity
)在内部管理其状态。上面的一般swap
可能会抛出(分配失败,内部T
的构造函数可能会抛出...),但是提供无抛出swap
实现很简单:template <typename T>
class vector {
T *b,*e,*c;
public:
void swap( vector<T>& rhs ) {
using std::swap;
swap( b, rhs.b );
swap( e, rhs.e );
swap( c, rhs.c );
}
//...
};
template <typename T>
void swap( vector<T>& lhs, vector<T>& rhs ) {
lhs.swap(rhs);
}
因为不能复制指针,所以上面的
swap
提供了不抛出保证,并且如果您始终按照上述模式实现swap
(using std::swap;
后跟对swap
的不合格调用),ADL将把它作为比std::swap
更好的匹配对象。关于c++ - 关于swap()操作的异常安全性-这怎么了?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11485776/