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)