nullptr
nullptr keyword indicates that an object handle, interior pointer, or native pointer type does not point to an object. nullptr is only valid when compiling with /clr (Common Language Runtime Compilation). You cannot initialize handles to zero; only nullptr can be used. Assignment of constant 0 to an object handle will produce a boxed Int32 and a cast to Object^. In unmanaged or traditional C++, it replaces the NULL keyword. nullptr can be used in the initialization of the following pointer types:
nullptr can be used for reference checking before using a pointer, for example:
nullptr can be used anywhere a handle or a native pointer can be used. nullptr can also be used as an argument for functions, for example:
|
nullptr is equivalent to Nothing in Visual Basic and null in C#. Function calls among languages that use these null mechanisms for error checking should be interpreted correctly. nullptr is not a type and is not supported for use with:
sizeof
typeid
typeobj
throw nullptr (although throw (Object ^)nullptr; will work)
A Program Example
The following sample code shows that nullptr and zero can be used interchangeably on native pointers.
// nullptr keyword
// compile with: /clr
#include "stdafx.h"
using namespace System;
class MyClass
{
public:
int i;
};
int main()
{
MyClass * pMyClass = nullptr;
Console::WriteLine("First statement: pMyClass = nullptr;");
if (pMyClass == nullptr)
System::Console::WriteLine("pMyClass == nullptr");
if (pMyClass == 0)
System::Console::WriteLine("pMyClass == 0");
pMyClass = 0;
Console::WriteLine();
Console::WriteLine("Second statement: pMyClass = 0;");
if (pMyClass == nullptr)
System::Console::WriteLine("pMyClass == nullptr");
if (pMyClass == 0)
System::Console::WriteLine("pMyClass == 0");
return 0;
}
Output:
The following example shows that nullptr is interpreted as a handle to any type or a native pointer to any type. In case of function overloading with handles to different types, an ambiguity error will be generated. The nullptr would have to be explicitly cast to a type.
// Another nullptr example
// compile with: /clr /LD
#include "stdafx.h"
using namespace System;
void funct(int *){Console::WriteLine("funct(int *)");}
void funct(int ^){Console::WriteLine("funct(int ^)");}
void funct_null()
{
// funct(nullptr); // C2668 error expected
// try one of the following lines instead
funct((int *) nullptr);
funct((int ^) nullptr);
}
int main()
{
funct_null();
return 0;
}
Output:
The following sample shows that casting nullptr is allowed and returns a pointer or handle to the cast type that contains the nullptr value.
// nullptr example
// compile with: /clr /LD
#include "stdafx.h"
using namespace System;
template <typename Ty>
void funct(Ty) {} // C2036 cannot deduce template type because nullptr can be any type
int main()
{
funct((Object ^) nullptr); // T = Object^, call f(Object ^)
// Delete the following line to resolve.
funct(nullptr);
funct(0); // T = int, call f(int)
}
The following sample shows that nullptr can be used as a function parameter.
// nullptr_4.cpp
// compile with: /clr
#include "stdafx.h"
using namespace System;
void f(Object ^ x)
{
Console::WriteLine("Test string...");
}
int main()
{
f(nullptr);
}
Output:
The following sample shows that when handles are declared and not explicitly initialized, they are default initialized to nullptr.
// nullptr program example
// compile with: /clr
#include "stdafx.h"
using namespace System;
ref class MyClass
{
public:
void Test()
{
MyClass ^pMyClass; // gc type
if (pMyClass == nullptr)
Console::WriteLine("It is NULL!");
else
Console::WriteLine("Go to hell...");
}
};
int main()
{
MyClass ^ xobj = gcnew MyClass();
xobj->Test();
}
Output:
The following sample shows that nullptr can be assigned to a native pointer when compiling with /clr.
// nullptr program example
// compile with: /clr
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int * inative = 0;
int * jnative = nullptr;
cout<<"inative = "<<inative<<endl;
cout<<"jnative = "<<jnative<<endl;
}
Output: