정보 & 소식/C, C++
nullptr 구현하기 전격 해부
어소트락
2017. 3. 7. 21:28
코드 자체로 설명을 해봅시다MAIN() 함수 부터 보시면 되겠습니다.// nullptr 구현.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>using namespace std;// nullptr 구현// 익명 클래스 여야 한다.// 내 포인터의 자료형과 이름이 존재한다면 이후 이 클래스를 재생성 하는 것을 막는다..const class {// 패딩 비트 sizeof를 했을시// 기본적인 클래스는 크기가 0이므로 이와 같은 포인터를 넣어줌으로서// sizeof시 크기를 포인터 크기와 같게 하기 위해서 사용한다.void* SizeMember;public:// 첫번째 템플릿 형변환 연산자// 이녀석은 모든 클래스 T나 자료형 T에 대한 포인터가 될수가 있어야 한다.template <class T>operator T*() const {return 0;}// 이건 모든 클래스나 자료형 C의 내부에서 생길수 있는 주소값 T에 대한 포인터로 형변환.// 어떤 클래스에 귀속되는 주소값이 존재한다.// 대표적인 예로는 맴버함수 포인터가 존재한다.template<class T, class C>operator T C::*() const{return 0;}private:// 정의해 놓음으로해서 절대로 주소값을 알지 못하게 한다.void operator&() const;// 곧바로 값을 선언함으로해서 단 1개의 Nullptr만이 사용가능하게 한다.} MyNullptr = {};//class {} const MyNullptr = {};//const class {} MyNullptr = {};class TestClass{public:TestClass() {}~TestClass() {}private:};int main(){// c++ 11부터 생긴 nullptr의 실제 구현 방법에 대해서 이야기 해보겠습니다.// c++의 코드를 통해서 이미 존재하는 통해서 nullptr을 구현한다면 어떤 모양이 될것인가에 대한 이야기입니다.// 일반적인 nullptr의 특성을 알아봅시다.// nullptr도 포인터이기는 하지만 주소값을 알아낼수는 없다.// void* NullAddress = &nullptr; // 에러// nullptr은 주소형이지만 모든 주소형에 들어갈수 있다.int* intAddress = nullptr;char* charAddress = nullptr;float* floatAddress = nullptr;TestClass* classAddress = nullptr;// 반대로 nullptr은 숫자가 아니기 때문에 정수형으로 변환될수는 없다.// int Zero = nullptr; // 에러// nullptr은 포인터형이기 때문에 크기는 sizeof시의 크기는 4바이트이다.int NullSize = sizeof(nullptr);cout << NullSize << endl; // 결과는 4.// nullptr이라는 것이 생긴이유는 다양한 경우에서의 주소값과 일반적인 0에 대한 형변환의 애매함 대문에 생겨났습니다.// 예전에 0이라는 숫자가 가리키지 않는 주소값과 정수형의 두가지 의미를 모두 가지고 있었습니다.// 물론 현재도 이는 상관이 없지만 숫자와 주소값의 형을 명확히 하는 것은 코드의 불확실성을 줄여주게 됩니다.void* Ptr = 0; // 0을 아직도 넣을수는 있지만 숫자와 주소의 구분이 미묘하게 된다.// 자 그러면 우리의 템플릿 nullptr을 만들어 봅시다.// 이와 같이 만들어 봤다면 사용해 봐야겠죠.// 자 다음과 같이 이상 없이 작동하는 것을 알수가 있습니다.int* MyintAddress = MyNullptr;char* MycharAddress = MyNullptr;float* MyfloatAddress = MyNullptr;TestClass* MyclassAddress = MyNullptr;int MyNullSize = sizeof(MyNullptr);cout << MyNullSize << endl;// 자 이와 같이 일반적인 nullptr와 완전히 똑같이 작동한다는 것을 볼수가 있습니다.// 그럼 nullptr 강의를 마치겠습니다.return 0;}