본문으로 바로가기

C++ 에서 상위 크래스로 부터 상속받은 하위 클래스에서 연산자재정의(Operator Overloading) 하는 방법을 알아보자.
난해한 분분이 아니지만 가끔 해당부분을 구현하려고 생각하면 막막 할때가 있다.
C++ 초급자에겐 무척 이해하기 어려울 지도 모르겠다.

예제 소스코드는 아주 짧지만 눈에 잘 보이지 않는 함점을 가지고 있다, 또한 Library 가 풍부하기 때문에 Operator Overloading을 직접 구현하는 경우는 잘 없기 때문에 익숙하지 않아서 막상 코딩을 하려면 막막하기만 하다.

class WRECT는 RECT 클래스를 변수로 가진다.(MFC에서 RECT는 사각형을 조작 하기 쉽도록 구현된 클래스이다)
WRECT에는 변수로 ID를 지정하고 있다.
클래스의 구현 목적은 윈도우창의 ID와 그에 해당하는 화면사각형의 크기를 임의로 조작 하고 관리하기 위해 고안된 것이다.

 
그리고 class CRectIDArray는 CArray를 상속 받아서    WRECT 클래스의 배열을 할당한다.
class CRectIDArray:public CArray<WRECT,WRECT> 를 보면 WRECT관련 배열을 할당하고 있음을 알 수 있다.
CArray는 동적 배열을 하당하고 쉽게 관리하는 기능을 가지고 있다.
그런데 여기서 조금 어려운 부분은 CArray가 Template Class를 사용하고 있으므로 익숙하지 않은 개발자에게 좀 어렵게 보인다.

 

class WRECT
{
public:
	WRECT()
	{
		ID=0;
		m_rect.left=0;
		m_rect.top=0;
		m_rect.right=0;
		m_rect.bottom=0;

	};
	WRECT(WORD id)
	{
		ID=id;
		m_rect.left=0;
		m_rect.top=0;
		m_rect.right=0;
		m_rect.bottom=0;
	}; 
	WRECT(WORD id,int x1,int y1,int x2,int y2)
	{
		ID=id;
		m_rect.left=x1;
		m_rect.top=y1;
		m_rect.right=x2;
		m_rect.bottom=y2;	 	
	}; 

	WORD ID;
	RECT m_rect;
};
class CRectIDArray:public CArray<WRECT,WRECT> 
{

public:
	CRectIDArray(){};
    int Add(WORD id )
	{
		return CArray<WRECT,WRECT>::Add( WRECT(id));
	};
	int Add(WORD id ,int x1,int y1,int x2,int y2)
	{
		return CArray<WRECT,WRECT>::Add( WRECT(id,x1,y1,x2,y2));
	};
	WORD& operator []( int nIndex )
	{
		WRECT p_r=CArray<WRECT,WRECT>::operator[](nIndex );
		return p_r.ID;
	};
    WORD operator []( int nIndex ) const
	{
		WRECT p_r=CArray<WRECT,WRECT>::operator[](nIndex );
		return p_r.ID;

	};
	WORD GetAt(int nIndex)const
	{
		return operator[](nIndex );		
	};
	WORD GetAt( int nIndex ,RECT& pRec)
	{	
		WRECT p_r=CArray<WRECT,WRECT>::GetAt(nIndex);
		pRec =p_r.m_rect;
		return p_r.ID;
	};
};

자 하나씩 확인해보자

CArray Class Members 를 보면
Attributes    

    GetSize Gets the number of elements in this array.
    GetUpperBound Returns the largest valid index.
    SetSize Sets the number of elements to be contained in this array.

Operations

    FreeExtra Frees all unused memory above the current upper bound
    RemoveAll Removes all the elements from this array. .

…………………….
Operators
  operator [] Sets or gets the element at the specified index.

와 같이 구성되 있는데

1. 부모클래스 연산자를 상속된 자식클래스에서 재정의

    WORD operator []( int nIndex ) const 와 같이 하위크래스에서 다시 정의 하였다.

    함수코드 내부에서 부보클래스의 연산자를 호출하기 위해서는 “부모클래스::operator []( int nIndex )”와 같이 호출하면 된다. 그런데 상위클래스가 Template 클래스를 사용하고 있으므로 하위클래스의 코드구현 부분에서    WRECT p_r=CArray<WRECT,WRECT>::operator[](nIndex ); 와 같이 호출 해야 한다.

2. 연산자 중복
    CRectIDArray의 코드를 보면 CArray<WRECT,WRECT> 를 상속 받고   WRECT와 관련된 어떠한 행동도 없다. 조금 이상하게 보이겠지만 여긴엔 연산자 중복의 개념이 숨어 있다. 

    operator []( int nIndex ) 는 CArray에도 있지만 상속된 CRectIDArray에도 있다, 그런데 두 클래스는 값을 반환하는 Type이 다르다.

    TYPE& operator []( int nIndex );   

    WORD CRectIDArray::operator []( int nIndex ) const
    WRECT CArray<WRECT,WRECT>::operator[](nIndex )
   이는 연산자가 중복되어 있으므로

 

void main()

{   

     WRECT mW[2];

     mW[0].ID=10;

     mW[1].ID=100;

   

     CRectIDArray   mArr; ///WRECT 를 배열로 추가한다

     mArr.Add(mW[0]);

     mArr.Add(mW[0]);

     mArr.Add(mW[1]);

     mArr.Add(mW[1]);

    

     mW[2];를 선언해서  WRECT 를 두개를 할당 했지만

     mArr는 4개의 WRECT 가 추가되어 있다.

:    int sz  =mArr.GetSize(): 를 실행하면 sz는 4를 반한한다.

   

      WORD id=mArr[0];//를 실행하면 WORD&CRectIDArray:: operator []( int nIndex ) 가 실행되어 id=10 이된다

      WRECT wr=mArr[0];//를 실행하면 CArray<WRECT,WRECT>::operator[](nIndex )가 실행되어 wr에는 WREC가 할당된다.

    

     }