STL에 관한 강의를 듣던 중, sort 의 사용자 정렬 기준을 정하는 함수를 구현하다가 오류가 발생하였다.
Person 클래스의 GetAge와 GetName 함수에서 오류가 발생한 것을 확인했고, 이 포인터가 const Person에서 Person & 타입으로 변환할 수 없다는 것을 확인할 수 있었다.
이 문제에 대해 조사를 해본 결과
C++에서 멤버 함수는 호출된 객체의 주소를 가리키는 'this' 포인터를 암묵적으로 사용한다.
const 객체에서 멤버 함수를 호출하면, 'this' 포인터는 const 포인터 타입으로 전달된다.
그러나 const가 아닌 멤버 함수를 호출하면, 일반 포인터 타입의 'this' 포인터를 필요로 한다.
이 차이로 인해 const 포인터를 일반 포인터로 변환하려고 시도하지만, 이는 안전하지 않기 때문에 컴파일러가 오류를 발생시킨 것이다.
아래 코드를 보면
class Person
{
private:
int age;
string name;
public:
Person(int age, string name) : age(age), name(name) {}
int GetAge() { return age; }
string GetName() { return name; }
};
bool compare(const Person& a, const Person& b)
{
if (a.GetAge() == b.GetAge())
{
return a.GetName() < b.GetName();
}
return a.GetAge() < b.GetAge();
}
int main()
{
vector<Person> people =
{
Person(39,"Bob"),
Person(21,"Alise"),
Person(29,"Dong"),
Person(29,"Hyeon"),
Person(5,"Chase")
};
sort(people.begin(), people.end(), compare);
return 0;
}
Compare 함수에서 멤버 함수를 호출하는 객체는 const Person 클래스 포인터이기 때문에 이 포인터가 호출하려는 멤버 함수 역시 const로 선언되어야 호출될 수 있지만, 멤버 함수 GetAge와 GetName 함수가 const로 선언되어있지 않았다는 것을 확인했다.