제주 탈출 일지

연산자 오버로딩 예제 본문

C++

연산자 오버로딩 예제

귀건 2020. 9. 30. 21:24
728x90
반응형

뇌를 자극하는 C++ STL의 연산자 오버로딩 예제를 공부하면서 느낀게 많아서 정리하려고 한다.

각각의 예제 소스코드를 올려놓았다.

chapter1. ov_operator.zip
6.51MB

#include <iostream>
using namespace std;

class Point
{
	int x;
	int y;
	
	public :
		Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
		void Print() const { cout << x << "," << y << endl;}
		int GetX() const { return x; }
		int GetY() const { return y; }
		
		void SetX(int argx) { x = argx;}
		void SetY(int argy) { y = argy;}
		
		friend const Point operator-(const Point& argL, const Point& argR);

};

// 내 맘대로 짠 버전. 
/*
const Point operator-(const Point& argL, const Point& argR)
{
	Point pt;
	pt.SetX(argL.GetX() - argR.GetX());
	pt.SetY(argL.GetY() - argR.GetY());
	
	return pt;  
}
*/

// 전역함수를 이용한 버전. 
/*
const Point operator-(const Point& argL, const Point& argR)
{
	return Point( argL.GetX() - argR.GetX(), argL.GetY() - argR.GetY() );	
} 
*/

// friend 함수를 사용한 버전 
const Point operator-(const Point& argL, const Point& argR)
{
	return Point(argL.x - argR.x, argL.y- argR.y);
}



int main()
{
	Point p1(2, 3), p2(5,5);
	Point p3;
	
	p3 = p1 - p2;
	
	p3.Print();
	
	return 0;
}

이 예제는 전역함수 오버로딩 예제이다. 전역함수 오버로딩을 사용하기 위해서는 클래스의 프라이빗 멤버에 접근해야 하는데, 그를 위해 필요한 것이 Getter,Setter 혹은 프렌드 함수이다. 

 

이 예제는 p3에 p1 - p2를 한 값을 대입하려하는데, 오버로딩을 어떻게 정의할 것이냐를 물어보고 있다.  함수들의 공톰점은 프라이빗 멤버에 접근하여 x값끼리 빼고, y값끼리 뺴서 그 값을 지닌 객체를 리턴하고 있습니다. 

제가 짠 버전이외의 다른 함수에서는 return Point( 세부 인자... ) 형태로 반환을 진행하는데, 여기서 Point()는 암시적인 객체 호출로 이름이 없는 Point형 객체이다.

 

 

그 다음은 문제 4번이다.

#include <iostream>
using namespace std;
#include <cstring>

class String
{
	char buf[100]; 
	
	public :
		
		String(const char* sz) {strcpy(buf, sz);}
		
		operator const char* ()
		{		
			return buf;
		}
		
	
};


int main()
{

	String s("Hello");

	const char* sz = s; //buf의 주소가 포인터 sz에 저장됨. 중요중요!!!!!! 
	
	cout << sz << endl;


	return 0;

이 문제는 

"String s("Hello");

const char* sz = s;" 가 성립하기 위해서 String 클래스를 정의하라. 가 문제였다.

 

내가 이 문제에서 엄청나게 삽질을 했는데, 나는 당연히 operator=에 대한 오버로딩을 하라고 생각했다.

근데 막상 짜려고 하니, 이 operator를 정의한 클래스의 객체가 이 연산을 호출해야 사용이 가능한데, const char* sz가 먼저 나와서 String 클래스의 s가 단순 대입을 시도하고 에러가 나는,,, 그런 인피니티에 빠졌다.

 

결국 못풀고 답을 봤는데, operator const char*() 를 정의하더라...

(감정변화 : ?? -> 헐.. -> 난이거못풀었겠다.)

 

C++ 참고서를 찾아보니, const char* sz = s;에서는 암시적으로 데이터 변환을 시도한다. sz는 char* 형이고 s는 String형이기 때문. 따라서 const char* sz = (const char*)s;를 컴파일러에서 자동으로 실행시켜주는 것과 같은 말이다. 

 

따라서 operator const char* 형 연산을 정의해야 컴파일러에서 이 연산을 가져다가 저 문장에 적용하여 에러가 생기지 않는다. 

 

문제 5번인데 참고해보길 바란다. 문제는 main의 있는 내용이 주어지고, 그 내용을 컴파일할 수 있도록 클래스를 작성하는 것이다.

#include <iostream>
using namespace std;
#include <cstring>
 
//얕은 복사. 
/*
class String
{
	char buf[100];
	public :
		String(const char* sz)
		{
			strcpy(buf, sz);
		}	
};
*/

//깊은 복사. 
class String
{
	char* buf;
	public:
		String(const char* sz)
		{
			buf = new char[strlen(sz) + 1];
		}
		String()
		{
			delete [] buf;
		}
		const String& operator=(const String& arg)
		{
			delete [] buf;
			buf = new char[strlen(arg.buf) + 1];
			strcpy(buf, arg.buf);
			
			return *this;
		}
};

int main()
{

	const char* sz = "Hello!";
	String s("Hi~!");
	s = sz;
		
	return 0;
}

 

 

다시금 느껴지는 띵언.

기본이 중요하다. 

 

728x90
반응형

'C++' 카테고리의 다른 글

string 형 처리.  (0) 2020.10.10
vector 컨테이너  (0) 2020.10.10
양방향 연결리스트(DLinkedList) - C++  (0) 2020.09.03
스마트 포인터(smart pointer)  (0) 2020.08.18
템플릿 (함수, 클래스)  (0) 2020.08.17
Comments