C++/CLI에서의 연산자 오버로딩 패턴

  • Post author:
  • Post category:
  • Post comments:7 Comments
  • Post last modified:October 1, 2013

C++/CLI 템플릿 클래스에서 연산자 오버로딩 문제를 해결하는 간단한 방법을 소개할까 합니다. 아래 코드는 원문에서 베껴온 코드이고, 언급했다시피 결과는 이상하게도 **성공, 실패** 입니다.

// LibraryA.cpp : library file.
#include "stdafx.h"
#include <iostream>

using namespace System;

template<typename ABC>
public ref class ManagedClassA
{
public:
	int V;

	ManagedClassA(int v)
	{
		V = v;
	}

	static bool operator == (ManagedClassA^ a, ManagedClassA^ b)
	{
		// Return true if the fields match:
		return ( (a->V + b->V) % 2 == 0 );
	}

	static bool operator != (ManagedClassA^ a, ManagedClassA^ b)
	{
		return !(a == b);
	}
};

public ref class ManagedClassB : public ManagedClassA<int>
{
public:
	ManagedClassB(int v)
		: ManagedClassA(v)
	{
	}
};

// 단순 테스트용 클래스
public ref class Tester
{
public:
	static void Test1()
	{
		ManagedClassB^ b1 = gcnew ManagedClassB(1);
		ManagedClassB^ b2 = gcnew ManagedClassB(3);
		if(b1 == b2)
			System::Console::WriteLine("성공");
		else
			System::Console::WriteLine("실패");
	}
};


template<typename ABC>
public ref class ManagedClassC
{
public:
	int V;

	ManagedClassC(int v)
	{
		V = v;
	}

	static bool operator == (ManagedClassC^ a, ManagedClassC^ b)
	{
		// Return true if the fields match:
		return ( (a->V + b->V) % 2 == 0 );
	}

	static bool operator != (ManagedClassC^ a, ManagedClassC^ b)
	{
		return !(a == b);
	}
};

public ref class ManagedClassD : public ManagedClassC<int>
{
public:
	ManagedClassD(int v)
		: ManagedClassC(v)
	{
	}
};
// LibraryB.cpp : main project file.
#include "stdafx.h"

using namespace System;

void Test2()
{
	ManagedClassD^ b1 = gcnew ManagedClassD(1);
	ManagedClassD^ b2 = gcnew ManagedClassD(3);
	if(b1 == b2)
		System::Console::WriteLine("성공");
	else
		System::Console::WriteLine("실패");
}

int main(array<System::String ^> ^args)
{
	Tester::Test1();
	Test2();
    return 0;
}

아무래도 컴파일러 또는 링커 버그 같지만 확신은 못하겠군요. 어쨌거나 이 문제를 가볍게 회피하는 수단을 삽질 끝에 찾아냈습니다. 연산자 오버로딩을 이렇게 바꾸면 됩니다.

template<typename ABC>
public ref class ManagedClassC
{
public:
	int V;

	ManagedClassC(int v)
	{
		V = v;
	}

	virtual bool operator == (ManagedClassC^ b)
	{
		// Return true if the fields match:
		return ( (this->V + b->V) % 2 == 0 );
	}

	virtual bool operator == (ManagedClassC^ b)
	{
		return !(a == b);
	}
};

주의해 볼 곳은 `virtual` 키워드입니다. 재정의 가능한 메서드로 선언함으로써 컴파일러(또는 링커)가 지멋대로 메서드를 빼먹지 못하게 할 수 있는 것 같습니다. 참고로 연산자 == 는 맨처음 코드처럼 `static`으로 선언해도 되고, 위의 코드처럼 멤버 함수로 선언해도 됩니다. 만약 `static`으로 선언하고 싶다면 다음 코드처럼 고쳐야 합니다.

template<typename ABC>
public ref class ManagedClassC
{
public:
	int V;

	ManagedClassC(int v)
	{
		V = v;
	}

	static bool operator == (ManagedClassC^ a, ManagedClassC^ b)
	{
		// Return true if the fields match:
		return ( (a->V + b->V) % 2 == 0 );
	}

	static bool operator != (ManagedClassC^ a, ManagedClassC^ b)
	{
		return !(a == b);
	}

	virtual bool ReferenceEquals(ManagedClassC^ that)
	{
		return ManagedClassC::operator == (this, that);
	}

	virtual bool ReferenceNotEquals(ManagedClassC^ that)
	{
		return ManagedClassC::operator != (this, that);
	}

};
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
follow me
  • 싸이월드 법인가 뭔가 화제였는데 이런 게 훨씬 현실적인 접근이다 https://t.co/fSB9LiMYzO
    1 day ago
  • 시장을 좋게 보는 사람을 좋게 볼 근거를 찾고 그렇지 않은 사람은 나쁘게 볼 근거만 열심히 찾네. 그 반대로 해야 얻는 게 있을텐데
    1 day ago
  • 일본이 liberal country 라는 말이 마음에 걸리네 https://t.co/aLteP9gEE8
    2 days ago
Buy me a coffeeBuy me a coffee
×
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
Latest Posts