Modern C++ - nullptr
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include<algorithm>
using namespace std;
// Modern C++ (C++11 부터 나온 아이들)
// nullptr
class Knight {
public:
void Test() {
cout << "Knight::Test()" << endl;
}
};
Knight* FindKnight() {
//TODO
return nullptr;
}
void Test(int a) {
cout << "Test(int)" << endl;
}
void Test(int* a) {
cout << "Test(int*)" << endl;
}
// NullPtr 구현
class NullPtr{
public:
// 그 어떤 데이터형의 포인터든 호환이 된다~
template<typename T>
operator T* () const {
return 0;
}
// 그 어떤 타입의 멤버 포인터와도 치환 가능
template<typename C, typename T>
operator T C::* () const {
return 0;
}
private :
// 주소값을 꺼내오려할 경우 private이므로 접근 거부됨
void operator&() const; //주소값 &을 막는다.
//void operator&() const = delete; //주소값 &을 막는다.
}_nullptr;
template<typename T>
struct Func{
public:
};
int main()
{
// nullptr이 없던 때에는 0 or NULL로 표현함
// nullptr을 사용해도 실제로는 0이 들어가서 상관 없긴 함,
// 또 0이 너무 정수같은 느낌이라 가독성을 위해 NULL을 사용해도 상관 없음
// 문제는 포인터와 정수를 모두 받도록 오버로딩된 함수가 있을 경우
// 0과 NULL을 인자값으로 줄 경우 무조건 포인터가 아닌 정수로 인식한다는 것
Test(0);
Test(NULL); // 둘다 모두 Test(int)를 실행한다는 것을 알 수 있다.
// 이러한 문제를 해결하기 위해 nullptr을 추가하였다.
Test(nullptr);
// nullptr을 사용하는 이유: 오작동 방지!
auto knight = FindKnight();
// 실제로는 nullptr과 비교하는 비교문이지만
// auto를 사용했기 때문에 제 3자가 봤을 때 0의 의미가
// int 0인지 nullptr인지 빠르게 유추하기 어렵다
if (knight == 0) {
}
// nullptr을 사용할 경우 바로 알아차릴 수 있다.
if (knight == _nullptr) {
}
nullptr_t whoami = nullptr;
Knight* k2 = _nullptr;
void (Knight:: * memFunc)();
memFunc = &Knight::Test;
if (memFunc == _nullptr) {
}
// 결론 null 포인터가 필요할 때 0과 NULL을 사용하는 대신 nullptr을 사용하자!
return 0;
}
Reference
この問題について(Modern C++ - nullptr), 我々は、より多くの情報をここで見つけました https://velog.io/@sansam41/Modern-C-nullptrテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol