2015년 9월 8일 화요일

[C++11] nullptr

nullptr 란?
C++11 에서 지원하는 null pointer 상수


먼저 pointer 가 초기화될 수 있는 정수 값을 살펴보자.


정수 0은 모든 타입의 포인터에 암시적 형변환을 통해서 초기화 값으로 사용될 수 있다.
하지만 그 이외의 정수는 암시적 형변환이 적용되지 않아 포인터 초기화에 사용될 수 없다.
그렇다면 0을 void* 로 형변환하여 NULL 로 정의해서 사용한다면 어떨까?



foo(NULL); 를 호출할 때는 문제가 없다.
또한 C언어에서는 void* 가 다른 타입의 포인터로 암시적 형변환이 가능하다.
하지만, C++에서는 void* 이 다른 타입의 포인터로 암시적 형변환이 허용되지 않는다.
따라서 C++에서 goo(NULL); 을 호출하면 error 가 발생한다.

NULL 은 void* 이지 char* 가 아니기 때문이다.


그렇다면 C++에서는 NULL 을 어떻게 정의하고 있을까?


결국엔 말그대로 포인터에 null pointer 를 전달하고 싶어서 nullptr 이 필요한 것이다.


nullptr 은 integer 0 이 아닌,
포인터 0이기 때문에 int type 에 대입하면 error 가 발생한다.
다만, bool type 에는 형변환이 가능하다.

그렇다면 nullptr 의 정확한 정체는 무엇일까?

nullptr 의 타입은 nullptr_t 이고,

nullptr_t 타입의 특징은 다음과 같다.
1. 모든 타입의 포인터로 암시적 변환 가능
2. bool로 암시적 변환 가능
3. int 로 변환되지 않으나, 하지만 reinterpre_cast를 통한 변환은 가능

nullptr 을 전달해야 하는 간단한 예제를 살펴보자.

C++11 에서 제공하는 perfect forwarding 기법을 통해서
foo(int*) 함수를 wrapping 하는 function 을 만들어 호출하는 경우이다.
여기서는 perfect forwarding 이 요점이 아니므로 이것에 대한 설명은 다음으로 하도록 하고..

wrapFunc 함수에서는 T type으로 인자를 전달받아
foo 함수에 인자를 그대로 전달하게 되는데,
foo(int*) 함수의 경우, 인자로 int*를 전달받기 때문에
wrapFunc(foo, 0); 을 호출할 경우 error 가 발생한다.

결국엔 0을 전달하려 할 경우, nullptr 을 전달해야 할 것이다.

nullptr 가 단순히 null pointer 상수로 기억하기 보다 어떤 필요성이 있는지 생각하고 사용해야 할 것이다.

Reference : http://en.cppreference.com/w/cpp/language/nullptr












댓글 없음:

댓글 쓰기

[C++] meta programing

재귀 호출에 관해 template meta programming 을 적용한 예제를 살펴보자. #include using namespace std; int fact(int n){ if(n factorial 연산을 하는 일반적인 재귀 호출 함...