More C++ Idioms/异常安全swap
异常安全swap [编辑]
意图[编辑]
- 实现异常安全的有效的交换操作
- 提供便于泛型编程的一致接口
别名[编辑]
- Non-throwing swap
- Exception safe swap
动机[编辑]
交换的典型的实现可能是下面这样:
template<class T>
void swap (T &a, T &b)
{
T temp (a);
a = b;
b = temp;
}
这可能存在下面两个问题:
- 性能
- 由于获得和释放临时中间变量,将导致交换两个相同类型的体积庞大的复杂对象变得非常低效。
- 异常安全性
- 如果资源不可用,swap可能会抛出异常(出现这样的行为完全没有任何意义,事实上没有申请新资源的必要。)。因此这一实现不能用于拷贝复制原语。
解决方案和示例代码[编辑]
异常安全交换原语使用Handle Body原语来完成想要的效果。问题的抽象被分为两个具体的类,一个是handle,另一个是body。handle持有一个body的指针,交换的实现只是简单的交换指针,这样就可以保证不抛出任何异常,由于没有申请释放任何新的资源因此是非常高效的。
namespace Orange {
class String
{
char * str;
public:
void swap (String &s) // throw ()
{
std::swap (this->str, s.str);
}
};
}
虽然有效的异常安全的swap函数可以实现为一个成员函数(就像上面那样),异常安全swap原语比这个简单的情况更加接近于泛型编程。一个显式 std::swap 模板偏特化可以添加到 std 和该类自身的命名空间。
namespace Orange { // namespace of String
void swap (String & s1, String & s2) // throw ()
{
s1.swap (s2);
}
}
namespace std {
template <>
void swap (Orange::String & s1, Orange::String & s2) // throw ()
{
s1.swap (s2);
}
}
已知应用[编辑]
boost 智能指针 (例如 boost::shared_ptr)