c – 关于swap()操作的异常安全 – 那是怎么回事?

前端之家收集整理的这篇文章主要介绍了c – 关于swap()操作的异常安全 – 那是怎么回事?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我继续读这个swap()操作,像这样:
template<class T>
void swap (T &a,T &b)
{
  T temp (a);
  a = b;
  b = temp;
}

当我们处理异常安全时,是有问题的.

这是怎么了?
此外,我们如何解决呢?

解决方法

在一般实现中,假设T的任何操作都可以抛出,您不能提供强大的异常保证,这意味着在异常事件发生之前将状态与操作之前完全一致.即使T上的每个操作都提供了强大的异常保证:
template<class T>
void swap (T &a,T &b)
{
  T temp (a);          // [1]
  a = b;               // [2]
  b = temp;            // [3]
}

如果[1]抛出,输入将保持不变,这是很好的.如果[2]抛出,并假设强大的异常保证,值仍然不变,这是很好的.但是如果[3]抛出,则已经被修改,这意味着在异常传播到堆栈之后,调用者将被保留一个既不是原始状态也不是最终状态的状态.

编辑:此外,我们如何解决呢?

没有一般的解决方案.但在大多数情况下,您可以为您的类型提供一个异常安全交换操作.考虑通过使用三个指针(开始,结束,容量)内部来管理其状态的向量< T&gt ;.上面的一般交换可以抛出(无法分配,内部T的构造函数可能会抛出...),但提供无投掷交换实现是微不足道的:

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提供了无抛出保证,如果你总是按照上面的模式实现交换(使用std :: swap;后面是不合格的调用来进行交换),它将被ADL所接受比std :: swap更好的匹配.

原文链接:https://www.f2er.com/c/111963.html

猜你在找的C&C++相关文章