map을 사용할 때 포인터 타입을 사용하지 않는 이유.
첫번째 타입의 비교를 어떻게 할 것인가?
operator 구현
const wchar_t* => 문자열의 주소끼리 비교? ㄴㄴ
int main()
{
_wsetlocale(LC_ALL, L"korean");
set<int> setInt;
setInt.insert(100);
const wchar_t* ptr = L"문자열";
map<const wchar_t*, StdInfo> mapData;
map<const wchar_t*, StdInfo>::iterator mapIter;
StdInfo stu1(L"김남영", 26, MAN);
StdInfo std2(L"김민성", 22, MAN);
mapData.insert(make_pair(L"김남영", stu1));
mapData.insert(make_pair(L"김민성", std2));
mapIter = mapData.find(L"김민성");
if (mapIter == mapData.end())
{
wcout << L"데이터를 찾을 수 없다." << endl;
}
else
{
wcout << L"이름 : " << mapIter->second.m_name << endl;
wcout << L"나이 : " << mapIter->second.m_age << endl;
wcout << L"성별 : ";
if (MAN == mapIter->second.m_gender)
{
wcout << L"남자" << endl;
}
else if (WOMAN == mapIter->second.m_gender)
{
wcout << L"여자" << endl;
}
else
{
cout << L"알 수 없음" << endl;
}
}
return 0;
}
일단 이렇게 가능하다.
지금 wchar_t가 한 문자당 2바이트인데
이것을 cout 으로 출력을 할려고하면 안됨.
wcout으로 출력해야하고
콘솔창에 아무것도 안뜨거나 이상하게 뜰 수 있는 이유는
정확하게는 모르지만 UTF 문제임
그래서
_wsetloacle(LC_ALL, L"korean");
넣어 줘야함.
우리가
map<const wchar_t*, StdInfo> mapData;
이렇게 선언 했는데
타입으로 const wchar_t* 를 넣어 주게되면
정말 문자열로 비교를 해서 "이진 탐색 트리"를 구성했다고 볼 수 없다.
문자열의 정체는 "주소값"이다.
주소값끼리 "비교연산" 하면 그냥 주소값의 크기를 비교해버리게 되니까..
문자가 누가 더 작고 그런것을 비교한게 아니라.
이렇게 찾을 수 있었던 이유는 find할때 문자열의 주소가 같았기 때문이다.
문자가 동일해서 찾은게 아니라! 주소값이 동일해서 찾은것이다.
map<const wchar_t*, StdInfo> mapData;
의 첫번째 타입을
문자열 객체를 다루는 것을 넣어주어야한다.
즉, 문자열을 다루는 클래스를 넣어 주어야한다.
이렇게 문자열 클래스 타입을 넣어 주어야한다.
string 헤더를 참조를 하면 문자열 클래스 사용이 가능하다.
지금 이녀석은 문자열 자체를 저장하고 있는데
원래는
wchar_t myArr[10] = L"abcdefg";
이렇게 선언 초기화를 해주면 L"abcdefg"라는 데이터를 배열에다가
"복사"를 해주는 것이다.
https://velog.io/@starkshn/CPP%EC%96%B4%EC%86%8C35%EB%AC%B8%EC%9E%90%EC%97%B4-1
마찬가지로
wstring str;
str = L"asdasd";
이 문자열 객체에 문자열을 집어 넣게되면은
(operator = 대입연산자 구현되어있음.)
본인이 자체적으로 가지고있는 "공간"안에
L"asdasd" 이 문자열을 가지고온다.
그러니까 wstring str의 str이라는 객체는
문자열 데이터(L"asdasd")를 따로 "관리"를 하고있는 것이다.
L"asdasd"의 주소를 관리 하는게 아니라.
읽기 전용 메모리 주소를 가르키는게 아니다❗
자체적으로 문자열을 관리를 한다.
이러한 operator들도 overloading이 되어있는 것이다.
ㄴㄴ 안됨.
그냥 느낌이 와야됨 이제는
"동적 할당"으로 늘리겠지 ㅄ아.
이렇게 무한정 넣기 ㄱㄴ? ㄴㄴ ㅂㄱㄴ.
배열을 처음부터 크게 할당 하는거 아님 ㅋㅋ!
이어붙일 때 힙메모리 구조를 받는다.
그렇다면
wstring은 우리가 배운 자료구조 중에 뭐랑 제일 비슷하노??
list랑 제일 비슷? (ㄴㄴ 병신아 )
굳이 따지자면 "가변 배열"이랑 가장 유사.
str은 "자체적인 힙메모리 영역"을 들고있기 때문에
수정이 "가능"함.
str1 == str2
비교하면은
각자가 관리를 하고있는 주소를 비교를 하는 것이겠나?
ㄴㄴ.
문자열 하나하나를 다 비교를 해서 싹다 같으면 같다라고 인식을 할 것이다.
< , > 누가 크냐 작냐 따지는 것도 가능.
wstring을 map의 첫번째 타입으로 지정하게되면은
map은 템플릿이다 보니까
첫번째 타입으로 지정해준 객체들 간에 비교 연산자들을 통해서
루트의 왼쪽으로 갈지 오른쪽으로 갈지 정할 것이다.
그런데 첫번째 타입이
다양한 operator를 제공하는(구현이 되어있음)
wstring타입이라
map이 내가 넣어준 wstring (Key) 끼리 비교를 할 수 있다.
그러니까 const wchar_t* 에서 나타난 문제가 없어 질 것이다.
"문자 자체"를 비교를 할 것이기 때문에.
구냥 MyClass라고 아무렇게 클래스만들고
이렇게 make_pair 해서 넣어주게 되면은
'<' 라는 비교 연산자가 구현되어있지 않단다.
결과적으로 안되는 이유는
mapStdInfo는 template이다.
그런데 우리가 만든 operator가 구현되어있지 않은 클래스를
이진 탐색 트리로 구현을 할 때,
insert를 할 경우 루트에서부터 큰지 작은지를 비교를
첫번째 타입인 Key로 비교를 할껀데
'>', '>' 와 같은 operator를 구현해 놓지 않은 클래스들끼리 어떻게 비교를 해서
이진트리에 밀어 넣을 꺼임?
그리고 탐색은 어떻게 할꺼임??
기본 포인터 자료형이기 때문에
첫번째 인자 Key값으로 넣어도 비교가 가능함.
그냥 주소 번지수가 크면 큰것이고 작으면 작은 그런거.
따라서 문자열 클래스 wstring으로 넣어 주어야한다.
다른 클래스도 되는데
그 클래스안에 operator들이 구현이 되어 있어야한다.