공부/C || C++

C++ 변환 연산자(Conversion Operator)

sudo 2021. 8. 28. 01:29

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로 변환돼서 리턴되기 때문에 가능한 것이다.