【C++11】nullprtの導入

2301 ワード

1.nullptrが導入された理由nullptrが導入された理由をNULLから説明する.CとC++プログラマーにとって、NULLに慣れていないに違いない.しかしCとC++のNULLは等価ではない.NULLはポインタがオブジェクトを指さないことを示すが、問題はNULLがキーワードではなくマクロ定義(macro)であることである.
1.1 NULLのCでの定義Cでは、NULLをvoid*ポインタ値0として定義する習慣があります.
#define NULL (void*)0
同時にNULLを整数0として定義することも可能である
1.2 NULLのC++における定義はC++にあり、NULLは整数0として明確に定義されている.
// lmcons.h   NULL   
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

1.3 C++がNULL上で不完全な互換性Cを選択した理由根本的な原因はC++のリロード関数と関係がある.C++はマッチングパラメータのメカニズムを探索することによって最適マッチング(best-match)の関数を見つけようとするが,void*の暗黙型変換をサポートし続けると意味二義性(syntax ambiguous)の問題をもたらす.
//           
void foo(int i);
void foo(char* p)

foo(NULL); // which is called?

2.nullptrの適用シーン
2.1コンパイラnullptrをサポートするコンパイラであれば、NULLのマクロ定義の代わりにnullptrを直接使用する必要があります.正常に使用する過程で彼らは完全に等価です.
コンパイラの場合、Visual Studio 2010はnullptrを含むC++0 xのほとんどの特性をサポートし始めました.VS 2010以前のバージョンでは、このキーワードはサポートされていません.
Codeblocks10.5付属のG++4.4.1 nullptrはサポートされていません.4.6.1にアップグレードするとnullptrをサポートできます(-std=c++0 xコンパイルオプションをオンにする必要があります).
2.2使用方法0(NULL)とnullptrは、次の例のようにスワップできます.
int* p1 = 0;
int* p2 = nullptr;

if(p1 == 0) {}
if(p2 == 0) {}
if(p1 == nullptr) {}
if(p2 == nullptr) {}
if(p1 == p2) {}
if(p2) {}
nullptrを整形に割り当てることはできません.次の例です.
int n1 = 0;             // ok
int n2 = nullptr;       // error

if(n1 == nullptr) {}    // error
if(n2 == nullptr) {}    // error
if(nullprt) {}          // error
nullptr = 0             // error
上記のリロード問題でnullptrを使用するとchar*が呼び出されます.
void foo(int)   {cout << "int" << endl;}
void foo(char*) {cout << "pointer" << endl;}

foo(0);       // calls foo(int)
foo(nullptr); // calls foo(char*)

3.シミュレーションnullptrの実装一部のコンパイラはc++11の新しいキーワードnullptrをサポートしていません.また、シミュレーションでnullptrを実装することもできます.
const
class nullptr_t_t
{
public:
    template<class T>           operator T*() const {return 0;}
    template<class C, class T>  operator T C::*() const { return 0; }
private:
    void operator& () const;
} nullptr_t = {};
#undef NULL
#define NULL nullptr_t