C++ 11の下でライブラリをテストしています(つまり、-std=c++11
)。ライブラリはauto_ptr
と次のパターンを使用します:
Foo* GetFoo()
{
autoptr<Foo> ptr(new Foo);
// Initialize Foo
ptr->Initialize(...);
// Now configure remaining attributes
ptr->SomeSetting(...);
return ptr.release();
}
C++ 11はauto_ptr
を非推奨としたので、それから離れたいと思います。
ただし、コードはC++ 03とC++ 11の両方をサポートしているため、auto_ptr
をヤンキングするのは簡単ではありません。また、ライブラリには外部依存関係がないことに言及する価値もあります。 C++ 03を使用します。 Autotools、Cmake、Boostなどは使用しません...
C++ 03との互換性を維持しながら、C++ 11のauto_ptr
から離れるように設計変更をどのように処理する必要がありますか?
ほとんどの点で、 std::unique_ptr
は std::auto_ptr
の代わりにドロップイン(ただしより安全)されています。 )unique_ptr
またはauto_ptr
のどちらかを使用するようにコードに指示する以外に、必要なコード変更が必要です。
これを行うにはいくつかの方法があります(それぞれ独自のリストトレードオフが付属しています)。提供されたコードサンプルを考えると、最初の2つのオプションのどちらかを優先します。
#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
トレードオフ;
auto_ptr
の名前をグローバル名前空間に導入します。独自の「プライベート」名前空間であると定義することで、これを軽減できます。auto_ptr
は完全に削除されると思います)、より簡単に検索して置き換えることができますtemplate <typename T>
struct my_ptr {
#if __cplusplus >= 201103L
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
トレードオフ;
auto_ptr
をコードでmy_ptr<T>::ptr
のようなものに変更する必要があります多少議論の余地がありますが、std
クラスをベースとして持つという警告に我慢する準備ができている場合
#if __cplusplus >= 201103L
template <typename T>
using my_ptr = std::unique_ptr<T>;
#else
template <typename T>
class my_ptr : public std::auto_ptr<T> {
// implement the constructors for easier use
// in particular
explicit my_ptr( X* p = 0 ) : std::auto_ptr(p) {}
};
#endif
トレードオフ;
ポインターを新しいクラスにラップし、必要な関数をメンバーに集約します
template <typename T>
class my_ptr { // could even use auto_ptr name?
#if __cplusplus >= 201103L
std::unique_ptr<T> ptr_;
#else
std::auto_ptr<T> ptr_;
#endif
// implement functions required...
T* release() { return ptr_.release(); }
};
トレードオフ;
#if __cplusplus >= 201103L
template<typename T>
using MyPtr = std::unique_ptr<T>;
#else
#define MyPtr std::auto_ptr
#endif
新しい言語バージョン、別名C++ 11以降では、エイリアスタイプは正しいスマートポインターにマップされます。 std :: auto_ptrに固有のAPIに実際に依存するユーザーコードは、コンパイラによってフラグが付けられます。これは、実際に修正されることを最終的に保証するものです。
レガシーc ++ 03モードでは、タイプエイリアスはマクロです。これは全体ですが、結果の構文MyPtr<T>
は、残りのコード全体でC++ 11の場合と同じです。
これを設定するには、すべてのauto_ptr変数を見つけてMyPtr
に変更する必要があります。