안녕하세요. BlockDMask 입니다.
여러분 std::map, std::set 아시죠? key값을 이용해서 데이터를 저장하는 container 이잖아요.
혹시 map, set의 공부가 필요하시다면 여기 링크를 타고 다녀오셔도 좋습니다.
여러분은 map과 set의 key값을 어떤걸로 쓰고 계셨나요? string? int? float?
네 맞습니다. 우리는 이렇게 기본적인 데이터 타입을 key값으로 쓰고 있었습니다.
하지만, 바로 오늘! 이 포스트를 보고 난 후! 부터는
C++ 맵, 셋에서 key값을 class, struct 우리가 직접 만든 타입(user defined type)으로 쓸수 있을것입니다.
std::map, std::set에서 키값을 일반 타입 string, int 등등이 아니라 user defined type으로 사용할 수 있는 방법! 바로 들어가시죠.
<목차>
1. 클래스, 구조체를 map, set의 키값으로 만드는 방법.
2. map, set의 키값을 구조체 클래스로 가지는 예제.
1. 클래스, 구조체를 map, set의 키값으로 만드는 방법.
▶ 무엇을 추가하면 map, set의 키값에 클래스 구조체를 넣을수 있을까?
map, set을 생각해보면 균형 이진트리로 구현되어 있는 연관 컨테이너 입니다.
그 트리에서 find의 결정적인 역할을 하는게 바로 KEY 입니다.
이 key값은 이진트리에서 탐색을 할 수 있는 조건이 되어야하는데요.
그렇기 때문에 대소비교가 가능해야합니다.
클래스들을 <, > 기호를 통해서 대소비교가 가능하게 할수 있는 방법. 무엇이 있을까요?
네 맞습니다. operator가 있습니다.
바로바로 operator < 를 재정의 해주기만 하면 map, set의 key값으로 class, struct를 사용할 수 있습니다.!
▶ 클래스나 구조체 내부에 operator< 를 재정의 하는 방법
클래스, 구조체 내부에 아래와 같이 정의 및 선언합니다.
반환형은 bool 타입이고, 매개변수로는 현재 클래스와 동일한 클래스 타입으로 const & 형태로 받습니다.
bool operator<(const 클래스명& 변수명) const
{
//비교구문을 통해 true, false를 반환.
}
예를들어 아래와 같은 클래스가 있다고 가정하면 이렇게 operator를 재정의 하시면 됩니다.
class Human
{
private:
int age;
int height;
public:
Human(int _age, int _height) : age(_age), height(_height){}
bool operator<(const Human& rhs) const
{
if (age != rhs.age) //age 먼저 비교
{
return age < rhs.age;
}
return height < rhs.height; // age가 같으면 height 비교.
}
}
2. map, set의 키값을 구조체 클래스로 가지는 예제.
map의 key가 클래스인 예제.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include<iostream> #include<map> //map #include<utility> //make_pair using namespace std; class Human { private: int age; int height; public: Human(int _age, int _height) : age(_age), height(_height){} bool operator<(const Human& rhs) const //이게 핵심! { if (age != rhs.age) { return age < rhs.age; } return height < rhs.height; } }; int main(void) { std::map<Human, int> m; //map 선언 Human hArr[] = { Human(30, 180), Human(30, 170), Human(30, 160), Human(22, 110), Human(22, 100), Human(42, 168), Human(51, 170) }; //map의 key 값이될 클래스 배열 int num = 0; //map의 value가 될 아무값. for (Human human : hArr) { m.insert(make_pair(human, num)); //클래스가 map의 키 값으로 잘 들어가네요? num++; } if (m.find(Human(30, 160)) != m.end()) //map의 키값 검색이 잘되네요? { cout << "map에 Human(30, 160)이 있소." << endl; } else { cout << "map에 Human(30, 160)은 없소." << endl; } return 0; } | cs |
▶ 결과
opeator< 가 재정의된 Human클래스가 map의 키값으로 잘 들어가있는걸 확인할 수 있습니다.
▶ 만약에 operator<가 없는 클래스를 키값으로 쓰려고 하면 아래와 같이 컴파일 에러가 나게 됩니다.
이렇게 오늘은 "map에 키값으로 클래스"를 넣는 방법에 대해 알아보았습니다. 궁금한점이나
C++에 대해서 특정한게 알고싶다 하시는 분은 댓글 편하게 달아주세요.
'<개인공부> > [C++]' 카테고리의 다른 글
[C++] enum class (scoped enum) 에 대해서 (5) | 2020.07.30 |
---|---|
[C++] auto 타입추론에 대해서 (3) | 2019.12.14 |
[C++] minmax() 최대값 최소값을 동시에 구하는 함수에 대해서 (0) | 2019.11.25 |
[C++] 최초값, 최대값 함수 min, max 에 대해서 (클래스, vector 사용법까지) (1) | 2019.11.22 |
[C++] 파일입출력(ofstream, ifstream)에 대해서. (2) | 2019.11.18 |
[C++] reverse 문자열을 거꾸로 하는 함수에 대해서 (0) | 2019.11.13 |
[C++] string 클래스, 문자열에 대해서 (총정리) (39) | 2019.03.29 |
[C++] range based for, 범위기반 for 반복문에 대해서. (1) | 2019.03.25 |