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로 선언되어있지 않았다는 것을 확인했다.
*수정된 코드
더보기

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Person
{
private:
int age;
string name;
public:
Person(int age, string name) : age(age), name(name) {}
//멤버 함수 const 선언
int GetAge() const { return age; }
string GetName() const { 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;
}

People 클래스의 멤버 함수를 const로 선언하였고 정상적으로 정렬할 수 있게 되었다.
'내배캠 > TIL' 카테고리의 다른 글
24.12.27 (금) (0) | 2024.12.27 |
---|---|
24.12.26 (목) (0) | 2024.12.26 |
24.12.24 (화) (0) | 2024.12.24 |
24.12.23 (월) (2) | 2024.12.23 |
24.12.21 (토) (2) | 2024.12.21 |