본문 바로가기

Programming/CPP11&14

[C++11] NULL을 대체하는 nullptr

반응형

C++이 2011년에 최신 개정판이 추가되었습니다.

기존에 C++0x로 불리다가 정식으로 채택되면서 C++11로 이름이 변경 되었습니다.

C++11은 개정된 년도를 따는 기존의 방식에 따라서 이름이 붙여졌습니다.

이전에 개정된 TR1(Technical Report 1)이 STL의 기능적인 추가에 치중했다면

이번 C++11은 C++의 기본 문법적인 부분에 변경이 있습니다.

문법적인 변경 사항에 대해서 하나하나 살펴보고자 합니다.

첫 번째 변경 사항은 nullptr 입니다.

nullptr은 NULL을 대체하게끔 만들어졌습니다.

기존 NULL의 문제점

C++ 03 4.10 절에서 0은 integer 상수와 널 포인터 상수 두 개의 기능을 갖는다고 되었습니다.

이 정의는 K&R C의 정의에 기반하고 있습니다.

여기서 문제가 발생되기 시작합니다.

C++에서는 함수 오버로딩이라는 기능이 존재합니다.

인자의 갯수나 타입에 따라서 이름이 같은 다른 함수를 만들어낼 수 있게 된 것입니다.

문제가 생길 소지를 코드로 보겠습니다.

#include <iostream>
using namespace std;

void func(int n)
{
	cout << "void func(int) called." << endl;
}

void func(char* p)
{
	cout << "void func(char*) called." << endl;
}

int main()
{
	func(0);
	func(NULL);
	
	func(nullptr);

	return 0;
}

원하는 결과는 다음과 같은 출력이었을 것입니다.

하지만 결과는 다음과 같이 출력됩니다.

이것은 애초에 NULL의 정의가 0으로 되어있기 때문에 발생하는 문제입니다.

또 이런 이상한 코드가 가능하게 만들기도 합니다.

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string szText(false);

	return 0;
}

이런 문제를 해결하기 위해서 NULL보다 NULL 포인터를 잘 표현할 수 있는 수단이 필요하게 됩니다.

nullptr의 구현안은 다음과 같이 되어 있습니다.

const // this is a const object...
class
{
public:
	template <class T> // convertible to any type
	operator T*() const // of null non-member
	{
		return 0;
	} // pointer...	
	template <class C, class T> // or any type of null
	operator T C::*() const // member pointer...
	{
		return 0;
	}
private:
	void operator&() const; // whose address can't be taken
} nullptr = {};

포인터의 변환을 허락하면서 다른 기능은 차단하는 nullptr이라는 const object를 생성합니다.

nullptr의 사용 예는 다음과 같습니다.

char* ch = nullptr; // ch has the null pointer value

char* ch2 = 0; // ch2 has the null pointer value

if( ch == nullptr ); // evaluates to true

char* ch3 = expr ? nullptr : nullptr; // ch3 is the null pointer value

sizeof( nullptr ); // ok

typeid( nullptr ); // ok

throw nullptr; // ok

잘못된 사용 예는 다음과 같습니다.

int n = nullptr; // error

if( n == nullptr ); // error

if( nullptr ); // error, no conversion to bool

if( nullptr == 0 ); // error

nullptr = 0; // error, nullptr is not an lvalue

nullptr + 2; // error

char* ch4 = expr ? 0 : nullptr; // error, types are not compatible

int n3 = expr ? nullptr : nullptr; // error, nullptr can’t be converted to int

int n4 = expr ? 0 : nullptr; // error, types are not compatible

nullptr이 사용 방법이 간단하고 문제점이 발생할 소지가 적기 때문에

NULL대신 nullptr을 사용하는 것이 안전한 코드를 작성하는 새로운 방법입니다.

반응형

'Programming > CPP11&14' 카테고리의 다른 글

[C++11] RValue Reference(1)  (0) 2014.12.14
[C++11] 이름 없는 함수, 람다(Lambda)(2)  (2) 2014.12.11
[C++11] 이름 없는 함수, 람다(Lambda)(1)  (0) 2014.12.11
[C++11] Range-Based For Loop  (0) 2014.12.11
[C++11] auto 키워드  (0) 2014.12.10