Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ STL set에 사용자 정의 데이터 타입 저장하는 방법

C++ STL에서 제공하는 set은 데이터를 항상 정렬된 상태로 유지하며, 중복 요소를 허용하지 않는 특수한 연관 컨테이너입니다. 기본적으로 int, double 같은 기본 자료형은 별도 설정 없이 바로 사용할 수 있지만, 직접 만든 클래스나 구조체 같은 사용자 정의 데이터 타입을 저장하려면 추가 작업이 필요합니다.

사용자 정의 타입에 필요한 조건: operator< 오버로딩

set은 내부적으로 요소들을 정렬하기 위해 비교 연산을 수행합니다. 따라서 사용자 정의 타입을 set에 넣으려면 해당 클래스에 operator<(보다 작음 연산자)를 오버로딩하여, 두 객체를 비교할 수 있는 기준을 반드시 제공해야 합니다.

만약 이 연산자가 정의되어 있지 않으면, set은 두 객체의 대소 관계를 판단할 수 없어 정렬 순서를 결정하지 못하고 컴파일 오류가 발생합니다. 아래 예제에서는 학생(Student) 객체를 학번(id)을 기준으로 정렬하도록 구현했습니다.

예제 코드

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

class Student {
    int id, marks;
public:
    Student(int id, int marks) {
        this->id = id;
        this->marks = marks;
    }
    // 학번(id)을 기준으로 정렬하기 위한 비교 연산자 오버로딩
    bool operator<(const Student& st) const {
        return (this->id < st.id);
    }
    void display() const {
        cout << "(" << id << ", " << marks << ")\n";
    }
};

int main() {
    Student s1(5, 70), s2(3, 86), s3(2, 91),
            s4(2, 60), s5(1, 78), s6(6, 53), s7(4, 59);

    // 학번(id)이 중복되는 객체는 삽입되지 않음
    set<Student> st_set;
    st_set.insert(s1);
    st_set.insert(s2);
    st_set.insert(s3);
    st_set.insert(s4);
    st_set.insert(s5);
    st_set.insert(s6);
    st_set.insert(s7);

    set<Student>::iterator it;
    for (it = st_set.begin(); it != st_set.end(); it++) {
        it->display();
    }
}

실행 결과

(1, 78)
(2, 91)
(3, 86)
(4, 59)
(5, 70)
(6, 53)

코드 설명 및 주요 포인트

위 예제에는 총 7개의 Student 객체를 삽입했지만, 출력 결과는 6개뿐입니다. 그 이유는 s3(2, 91)s4(2, 60)처럼 학번(id)이 동일한 객체가 존재하기 때문입니다. set은 비교 연산자를 기준으로 중복을 판단하므로, id가 같으면 점수(marks)가 다르더라도 하나의 요소만 저장됩니다.

정렬 기준으로 사용할 멤버 변수는 개발자가 자유롭게 선택할 수 있습니다. 예를 들어 this->marks < st.marks로 수정하면 점수를 기준으로 정렬됩니다. 또한 operator<를 const 멤버 함수로 선언해야 set 내부에서 안전하게 호출할 수 있으므로, 함수 끝에 const 키워드를 붙이는 것도 잊지 말아야 합니다.

이처럼 C++의 set은 비교 연산자만 적절히 정의해주면 어떤 사용자 정의 타입이든 자동으로 정렬되고 중복 없이 관리할 수 있는 강력한 도구입니다.