C++ 클래스에서는 변환 연산자(Conversion operator)라는 특이한 함수를 연산자 오버로딩할 수 있다. 예를 들어서 아래와 같이 CSharedPtr을 구현한 상태라고 생각해보자.
#pragma once
template <typename T>
class CSharedPtr
{
public:
CSharedPtr() :
m_Ptr(nullptr)
{
}
CSharedPtr(T* Ptr)
{
m_Ptr = Ptr;
if (m_Ptr)
m_Ptr->AddRef();
}
CSharedPtr(const CSharedPtr<T>& Ptr)
{
m_Ptr = Ptr.m_Ptr;
if (m_Ptr)
m_Ptr->AddRef();
}
~CSharedPtr()
{
if (m_Ptr)
m_Ptr->Release();
}
private:
T* m_Ptr;
public:
void operator = (T* Ptr)
{
// 기존에 가지고 있는 레퍼런스 객체가 있을 경우 카운트를 1 감소시켜준다.
if (m_Ptr)
m_Ptr->Release();
m_Ptr = Ptr;
// 새로 지정된 레퍼런스 객체가 있을 경우 카운트를 1 증가시켜준다.
if (m_Ptr)
m_Ptr->AddRef();
}
void operator = (const CSharedPtr<T>& Ptr)
{
// 기존에 가지고 있는 레퍼런스 객체가 있을 경우 카운트를 1 감소시켜준다.
if (m_Ptr)
m_Ptr->Release();
m_Ptr = Ptr.m_Ptr;
// 새로 지정된 레퍼런스 객체가 있을 경우 카운트를 1 증가시켜준다.
if (m_Ptr)
m_Ptr->AddRef();
}
// 변환연산자(operator conversion)
operator T* ()
{
return m_Ptr;
}
T* operator -> ()
{
return m_Ptr;
}
};
만약 CResourceManager라는 클래스가 아래와 같이 unordered_map의 value로 CSharedPtr<CTexture>를 갖도록 되어 있고 이미 unordered_map안에 element의 value는 CSharedPtr<CTexture>를 갖고 있는 상태로 insert 되어 있다고 생각해보자. 만약 이 unordered_map에서 key값을 이용해서 특정 CTexture*를 찾아서 return 해줘야 한다면 다음과 같이FindTexture를 구현할 수 있다.
class CResourceManager
{
private:
CResourceManager();
~CResourceManager();
private:
std::unordered_map<std::string, CSharedPtr<CTexture>> m_mapTexture;
public:
CTexture* FindTexture(const std::string& Name)
{
auto iter = m_mapTexture.find(Name);
if (iter == m_mapTexture.end())
return nullptr;
return iter->second;
}
};
m_mapTexture의 value는 CSharedPtr<CTexture>인데 FindTexture의 리턴 타입은 CTexture*이다. 이게 가능한 이유는 위의 CSharedPtr에서 변환 연산자가 정의되어 있기 때문에 iter->second로 리턴하면 변환 연산자가 호출돼서 CSharedPtr의 멤버 m_Ptr, 즉 CTexture* 타입의 m_Ptr로 변환돼서 리턴되기 때문에 가능한 것이다.
'공부 > C || C++' 카테고리의 다른 글
const 멤버 함수의 리턴 타입을 레퍼런스로 할 수 없는 이유/ const 멤버함수 내부에서 const가 아닌 멤버 함수를 호출할 수 없다 (0) | 2021.11.12 |
---|---|
C++ const가 붙는 위치에 따른 의미변화 (0) | 2021.09.01 |
C++ vector의 resize vs reserve (0) | 2021.08.25 |
C++ 오버라이딩시 반환 타입을 자식 클래스 타입으로 하면 반환 타입이 다르게 오버라이딩 된다 (0) | 2021.08.21 |
C++ 자식 클래스 복사 생성자 초기화 리스트에서 부모의 복사 생성자 호출하는 방법 (0) | 2021.08.17 |