Effective C++条項25
3900 ワード
異常を投げ出さないswap関数を書くことを考慮します
このセクションでは、効率的なswap関数をカスタマイズする方法について説明します.
std名空間におけるswapデフォルト関数は次のようになります.
著者らは,交換対象のデータが大きい場合,以上のswapの実行効率が遅くなることを見ることができ,このような状況を変えるために,以下の方法を提案した.
クラスの再定義
2つのWidgetオブジェクトの値を置き換え、そのpImplポインタを置き換えるだけで効率が向上します.では、swapをどのように定義しますか?次のようになります.
上記のコードから,我々の目的を達成し,2つのWidgetImplオブジェクトの交換を実現し,ポインタのみを交換することが分かった.もちろんここでは交換クラスWidgetを構築する必要があり,Widgetタイプのswapをフル特化する必要があり,関数体内でmember関数swapを定義する必要がある.
では、読者は迷って、大きな周りを回って、どのように直接メンバー関数swapを呼び出さないのか、これはあなたがswap(a,b)文を使うと、自動的に適切に一致する機能を持っているからです.お客様の使用に適しており、インタフェースの一貫性と簡易性を実現します.
次に、2つのクラスがtemplateである場合、上記の問題をどのように解決するかを紹介します.次のようになります.
名前空間を次のように再命名できます.
このセクションでは、効率的なswap関数をカスタマイズする方法について説明します.
std名空間におけるswapデフォルト関数は次のようになります.
namespace std{
template<typename T>
void swap(T& a, T& b)
{
T temp(a);
a=b;
b=temp;
}
}
class WidgetImpl{
public:
……
private:
int a,b,c; // ,
std::vector<double> b;
……
};
著者らは,交換対象のデータが大きい場合,以上のswapの実行効率が遅くなることを見ることができ,このような状況を変えるために,以下の方法を提案した.
クラスの再定義
class Widget{
public:
Widget(const Widget& rhs);
Widget& operator=(const Widget& rhs
{
…… // Widget , WidgetImpl
*pImpl=*(ths.pImpl);
……
}
……
private:
WidgetImpl* pImpl;// , Widget
};
2つのWidgetオブジェクトの値を置き換え、そのpImplポインタを置き換えるだけで効率が向上します.では、swapをどのように定義しますか?次のようになります.
calss Widget{
public:
……
void swap(Widget& other)
{
using std::swap;//
swap(pImpl, other.pImpl);
}
……
};
namespace std{
template<> // swap
void swap<Widget>(Widget& a, Widget& b)
{
a.swap(b); //
}
}
Widget w1,w2;
swap(w1,w2);// Widget swap.
上記のコードから,我々の目的を達成し,2つのWidgetImplオブジェクトの交換を実現し,ポインタのみを交換することが分かった.もちろんここでは交換クラスWidgetを構築する必要があり,Widgetタイプのswapをフル特化する必要があり,関数体内でmember関数swapを定義する必要がある.
では、読者は迷って、大きな周りを回って、どのように直接メンバー関数swapを呼び出さないのか、これはあなたがswap(a,b)文を使うと、自動的に適切に一致する機能を持っているからです.お客様の使用に適しており、インタフェースの一貫性と簡易性を実現します.
次に、2つのクラスがtemplateである場合、上記の問題をどのように解決するかを紹介します.次のようになります.
template<typename T>
class WidgetImpl{……};
template<typename T>
class Widget{……};
名前空間を次のように再命名できます.
namespace WidgetStuff{
……// WidgetImpl
template<typename T>// swap
class Widget{……};
……
template<typename T>
void swap(Widget<T>& a,//non-member, std
Widget<T>& b)
{
a.swap(b);
}
}
Widget<int> w1,w2;
swap(w1,w2);// WidgetStuff Widget<int> swap.