공부 중 메모/수업 예제 (KGCA)

Cpp 연산자 오버로딩 예제

라이피 (Lypi) 2018. 7. 13. 23:46
반응형

출처 : KGCA 게임 아카데미(http://www.kgcaschool.com/). 수업 예제 파일.


pt.h

#pragma once
#include <iostream>
using namespace std;

//const char& operator []() const;
//char& operator [] ();
//두 함수는 별개의 함수가 된다. ... const 함수냐 아니냐의 차이.

class pt
{
	static int dynamic;
	int x, y;
public:
	void SetPosition(int _x, int _y);
	void Move(int _x, int _y);
	void Show();

	//포인터 연산자 재정의
	pt* operator->();
	pt& operator* ();

	//증가 연산자 재정의
	pt operator++();      // ++p1(전위)
	pt operator++(int);  // p1++;(후위)

	// 이항연산자 p3 = p1 + p2
	pt operator+(const pt& np) const;

	// 이항연산자 p3 = p1 + 2, p3 = 2 + p1
	pt operator+(int n) const; // p2=p1*2;
	friend pt operator+(int n, const pt& np); // p2= 2 * p1;
	

	pt &operator=(const pt &pt);

	pt &operator+=(const pt &pt);
	pt &operator+=(int n);

	//의미 없는 장난질
	friend int operator+= (int& n, const pt& np);
	//friend pt& operator+= (int& n, pt& np);

	bool operator==(const pt &pt) const;
	bool operator!=(const pt &pt) const;

	int &operator[](int index);
	void *operator new(size_t size);
	void operator delete(void *p);

	//std::cout << *pFindA << *pFindB;
	friend ostream &operator<<(ostream &os, const pt &pt);
	friend istream &operator>>(istream &is, pt &pt);

	void (pt::*m_fp) ();	//함수 포인터 선언

	void Execute() {		//함수 포인터 실행
		if (m_fp != NULL)
		{
			(this->*m_fp)();
		}
	}
	void operator > (pt* the)
	{
		if (m_fp != NULL)
		{
			(the->*m_fp)();
		}
	}
public:
	pt();
	pt(int x, int y);
	pt(const pt& obj);

	~pt();

};

pt.cpp

#include "pt.h"

int pt::dynamic = 0;

//이 넷의 기본 형식은 이렇게 정해져 있다. 
pt*   pt::operator->()              
{ 
	//뭔가 새로운 작업
	return  this; 
}
pt&   pt::operator* ()              
{
	//뭔가 새로운 작업
	return *this; 
}
void* pt::operator new(size_t size) 
{
	cout << "동적생성된 수 : " << ++dynamic << endl;;
	return ::new pt; 
}
void  pt::operator delete(void* p)  
{
	cout << "동적생성된 수 : " << --dynamic << endl;;
	::delete p; 
}

//빡침 사칙연산은 더하기만 하자.

//전위 증가
pt pt::operator++(void) // ++p1
{
	++x, ++y;
	return *this;
}

//후위 증가
pt pt::operator++(int)  // p1--;
{
	pt temp = *this;
	++x, ++y;
	return temp;
}

//같은 타입끼리 연산
pt pt::operator+(const pt &np) const
{
	return pt(x + np.x, y + np.y);
}


//다른 타입과의 연산 p2=p1+2;
pt pt::operator+(int n) const // 
{
	return pt(x + n, y + n);
}

// p2= 2 + p1; (friend함수임) (교환법칙 정의)
pt operator+(int n, const pt &np) 
{
	return pt(np.x + n, np.y + n);
}

//대입 연산자
pt& pt::operator=(const pt &np) {
	x = np.x; y = np.y;
	return *this;
}

//증가 대입 연산자 (같은 타입에 대해서) pt1 += pt2
pt& pt::operator+=(const pt &np)
{
	x += np.x; y += np.y;
	return *this;
}

//증가 대입 연산자 (인트 타입에 대해서) pt1 += int1

pt& pt::operator+=(int n)
{
	x += n; y += n;
	return *this;
}

//int1 += pt1 은 할 수 있을까?
int operator+= (int& n, const pt& np) 
{
	//할 수 있지만 의미가 많이 다르다.
	n += np.x + np.y;
	return n;
}

//int1 += pt1 으로 pt를 리턴해서 pt1에 저장한다면?
//pt& pt::operator+=(int n) 이것과 차이가 없다. 괜히 헷갈리기만 하지.
//pt& operator+= (int& n, pt& np)
//{
//	//할 수 있지만 의미가 많이 다르다.
//	np.x += n; np.y += n;
//	return np;
//}

bool pt::operator==(const pt &pt) const
{	
	return (this->x == pt.x && this->y == pt.y);
	//&& 연산의 결과는 bool값이다.
}

bool pt::operator!=(const pt &pt) const
{
	return !(*this == pt);
	//이미 정의한 == 연산자를 이용하여 정의
}
	 

//인덱싱 연산
int& pt::operator[](int index)
{
	switch (index % 2) {
		case 0: return x; break;
		case 1: return y; break;
	}
}

//입출력 스트림 연산자 재정의.
ostream& operator<<(ostream &os, const pt &np)
{
	os << "(" << np.x << ", " << np.y << ")";
	return os;
}
istream& operator>>(istream &is, pt &np)
{
	is >> np.x;
	is >> np.y;
	return is;
}


void pt::SetPosition(int _x, int _y)
{
	x = _x;
	y = _y;
}
void pt::Move(int _x, int _y)
{
	x += _x;
	y += _y;
}
void pt::Show()
{
	printf("(%d,%d)\n", x, y);
}

pt::pt()
{
	cout << "constructor" << endl;
}

pt::pt(int x, int y)
{
	this->x = x;
	this->y = y;
	cout << "constructor" << endl;
}

pt::pt(const pt& obj)
{
	this->x = obj.x;
	this->y = obj.y;
	cout << "복사 생성자" << endl;
}

pt::~pt()
{
	cout << "Distructor" << endl;
}

main.cpp

#include "pt.h"

//함수 포인터 관련 ... 이해가 잘 안됨.
void (pt::*fp) ();
void Execute(pt* the)
{
	if (fp != NULL)
	{
		(the->*fp)();
	}
}

int main()
{
	pt p1(0, 0), p2, p3, p4;

	p2 = ++p1;
	cout << p2 << p1 << endl;

	p1->Show();
	(*p1)->Show();
	pt* pData = new pt();
	pData->Show();

	p3 = p1++;
	cout << p3 << p1 << endl;

	p4 = p2 + p3;
	cout << p4 << endl;
	
	pt p5(10, 20), p6, p7;
	p6 = p5 + 2;
	p7 = 2 + p5;
	cout << p6 << p7 << endl;

	if (p6 == p7) { cout << "같다" << endl; }
	if (p6 != p7) { cout << "다르다" << endl; }

	cout << p6[0] << p6[1] << endl;

	pt p8;
	cin >> p8; 
	cout << p8;

	pt* d = new pt;
	d->SetPosition(10, 10);
	cout << *d;

	//전역 함수 포인터
	fp = &pt::Show;
	Execute(d);

	//클래스멤버함수 함수포인터
	d->m_fp = &pt::Show;
	(*d) > &p8;
	d->Execute();

	delete d;

	return 0;
}


반응형