11. 연산자 오버로딩 2


출처: 윤성우 열혈강의 C++ 예제코드


11.1. 반드시 해야 하는 대입 연산자의 오버로딩

  • 디폴트 대입 연산자의 문제점
#include <iostream>
#include <cstring>
using namespace std;

class Person
{
	char * name;
	int age;
public:
	Person(char * myname, int myage)
	{
		int len=strlen(myname)+1;
		name=new char[len];
		strcpy(name, myname);
		age=myage;
	}
	void ShowPersonInfo() const
	{
		cout<<"이름: "<<name<<endl;
		cout<<"나이: "<<age<<endl;
	}
	
	~Person()
	{
		delete []name;
		cout<<"called destructor!"<<endl;
	}
};

int main(void)
{
	Person man1("Lee dong woo", 29);
	Person man2("Yoon ji yul", 22);
	man2=man1;
	man1.ShowPersonInfo();
	man2.ShowPersonInfo();
	return 0;
}
이름: Lee dong woo
나이: 29
이름: Lee dong woo
나이: 29
called destructor!
  • 디폴트 대입 연산자의 문제점 해결
#include <iostream>
#include <cstring>
using namespace std;

class Person
{
	char * name;
	int age;
public:
	Person(char * myname, int myage)
	{
		int len=strlen(myname)+1;
		name=new char[len];
		strcpy(name, myname);
		age=myage;
	}
	Person& Person::operator=(const Person& ref)
	{
		delete []name;

		int len=strlen(ref.name)+1;
		name= new char[len];
		strcpy(name, ref.name);
		age=ref.age;
		return *this;
	}
	void ShowPersonInfo() const
	{
		cout<<"이름: "<<name<<endl;
		cout<<"나이: "<<age<<endl;
	}
	
	~Person()
	{
		delete []name;
		cout<<"called destructor!"<<endl;
	}
};

int main(void)
{
	Person man1("Lee dong woo", 29);
	Person man2("Yoon ji yul", 22);
	man2=man1;
	man1.ShowPersonInfo();
	man2.ShowPersonInfo();
	return 0;
}
이름: Lee dong woo
나이: 29
이름: Lee dong woo
나이: 29
called destructor!
called destructor!
  • 유도 클래스에서 대입연산자 오버라이딩 시 기초 클래스 대입연산자 호출하기
#include <iostream>
using namespace std;

class First
{
private:
	int num1, num2;
public:
	First(int n1=0, int n2=0) : num1(n1), num2(n2)
	{  }
	void ShowData() { cout<<num1<<", "<<num2<<endl; }

	First& operator=(const First&ref)
	{
		cout<<"First& operator=()"<<endl;
		num1=ref.num1;
		num2=ref.num2;
		return *this;
	}
};

class Second : public First
{
private:
	int num3, num4;
public:
	Second(int n1, int n2, int n3, int n4) 
		: First(n1, n2), num3(n3), num4(n4)
	{  }
	void ShowData() 
	{
		First::ShowData();
		cout<<num3<<", "<<num4<<endl; 
	}

	
	Second& operator=(const Second &ref)
	{
		cout<<"Second& operator=()"<<endl;
		First::operator=(ref);
		num3=ref.num3;
		num4=ref.num4;
		return *this;
	}
	
	
};


int main(void)
{
	Second ssrc(111, 222, 333, 444);
	Second scpy(0, 0, 0, 0);
	scpy=ssrc;
	scpy.ShowData();
	return 0;
}
  • 이니셜라이저를 이용한 성능향상(함수호출 줄이기)
#include <iostream>
using namespace std;

class AAA
{
private:
	int num;
public:
	AAA(int n=0): num(n)
	{  
		cout<<"AAA(int n=0)"<<endl;
	}
	AAA(const AAA &ref): num(ref.num)
	{  
		cout<<"AAA(const AAA & ref)"<<endl;
	}
	AAA & operator=(const AAA &ref)
	{
		num=ref.num;
		cout<<"operator=(const AAA &ref)"<<endl;
		return *this;
	}
};

class BBB
{
private:
	AAA mem;
public:
	BBB(const AAA & ref)
		: mem(ref)
	{  }
};

class CCC
{
private:
	AAA mem;
public:
	CCC(const AAA & ref)
	{
		mem=ref;
	}
};

int main(void)
{
	AAA obj1(12);
	cout<<"*********************"<<endl;
	BBB obj2(obj1);
	cout<<"*********************"<<endl;
	CCC obj3(obj1);
	return 0;
}
AAA(int n=0)
*********************
AAA(const AAA & ref)
*********************
AAA(int n=0)
operator=(const AAA &ref)

11.2. 배열의 인덱스 연산자 오버로딩

  • const를 이용한 operator[] 오버로딩
#include <iostream>
#include <cstdlib>
using namespace std;

class BoundCheckIntArray 
{
private:
	int * arr;
	int arrlen;

	BoundCheckIntArray(const BoundCheckIntArray& arr) { }
	BoundCheckIntArray& operator=(const BoundCheckIntArray& arr) { }

public:
	BoundCheckIntArray(int len) :arrlen(len)
	{
		arr=new int[len];
	}
	int& operator[] (int idx)
	{
		if(idx<0 || idx>=arrlen)
		{
			cout<<"Array index out of bound exception"<<endl;
			exit(1);
		}
		
		return arr[idx];
	}
	int operator[] (int idx) const 
	{
		if(idx<0 || idx>=arrlen)
		{
			cout<<"Array index out of bound exception"<<endl;
			exit(1);
		}
		
		return arr[idx];
	}
	int GetArrLen() const 
	{
		return arrlen;
	}
	~BoundCheckIntArray()
	{
		delete []arr;
	}
};

void ShowAllData(const BoundCheckIntArray& ref)
{
	int len=ref.GetArrLen();

	for(int idx=0; idx<len; idx++)
		cout<<ref[idx]<<endl;
}

int main(void)
{
	BoundCheckIntArray arr(5);

	for(int i=0; i<5; i++)
		arr[i]=(i+1)*11;

	ShowAllData(arr);
	return 0;
}
  • 객체저장용 배열클래스 만들기
#include <iostream>
#include <cstdlib>
using namespace std;

class Point
{
private:
	int xpos, ypos;
public:
	Point(int x=0, int y=0) : xpos(x), ypos(y) {  }
	friend ostream& operator<<(ostream& os, const Point& pos);
};

ostream& operator<<(ostream& os, const Point& pos)
{
	os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
	return os;
}

class BoundCheckPointArray 
{
private:
	Point * arr;
	int arrlen;

	BoundCheckPointArray(const BoundCheckPointArray& arr) { }
	BoundCheckPointArray& operator=(const BoundCheckPointArray& arr) { }

public:
	BoundCheckPointArray(int len) :arrlen(len)
	{
		arr=new Point[len];
	}
	Point& operator[] (int idx)
	{
		if(idx<0 || idx>=arrlen)
		{
			cout<<"Array index out of bound exception"<<endl;
			exit(1);
		}
		
		return arr[idx];
	}
	Point operator[] (int idx) const 
	{
		if(idx<0 || idx>=arrlen)
		{
			cout<<"Array index out of bound exception"<<endl;
			exit(1);
		}
		
		return arr[idx];
	}
	int GetArrLen() const 
	{
		return arrlen;
	}
	~BoundCheckPointArray()
	{
		delete []arr;
	}
};

int main(void)
{
	BoundCheckPointArray arr(3);
	arr[0]=Point(3, 4);
	arr[1]=Point(5, 6);
	arr[2]=Point(7, 8);

	for(int i=0; i<arr.GetArrLen(); i++)
		cout<<arr[i];

	return 0;
}
  • 포인터저장용 배열클래스 만들기
#include <iostream>
#include <cstdlib>
using namespace std;

class Point
{
private:
	int xpos, ypos;
public:
	Point(int x=0, int y=0) : xpos(x), ypos(y) {  }
	friend ostream& operator<<(ostream& os, const Point& pos);
};

ostream& operator<<(ostream& os, const Point& pos)
{
	os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
	return os;
}

typedef Point * POINT_PTR;

class BoundCheckPointPtrArray 
{
private:
	POINT_PTR * arr;
	int arrlen;

	BoundCheckPointPtrArray(const BoundCheckPointPtrArray& arr) { }
	BoundCheckPointPtrArray& operator=(const BoundCheckPointPtrArray& arr) { }

public:
	BoundCheckPointPtrArray(int len) :arrlen(len)
	{
		arr=new POINT_PTR[len];
	}
	POINT_PTR& operator[] (int idx)
	{
		if(idx<0 || idx>=arrlen)
		{
			cout<<"Array index out of bound exception"<<endl;
			exit(1);
		}
		
		return arr[idx];
	}
	POINT_PTR operator[] (int idx) const 
	{
		if(idx<0 || idx>=arrlen)
		{
			cout<<"Array index out of bound exception"<<endl;
			exit(1);
		}
		
		return arr[idx];
	}
	int GetArrLen() const 
	{
		return arrlen;
	}
	~BoundCheckPointPtrArray()
	{
		delete []arr;
	}
};

int main(void)
{
	BoundCheckPointPtrArray arr(3);
	arr[0]=new Point(3, 4);
	arr[1]=new Point(5, 6);
	arr[2]=new Point(7, 8);

	for(int i=0; i<arr.GetArrLen(); i++)
		cout<<*(arr[i]);

	delete arr[0];
	delete arr[1];
	delete arr[2];
	return 0;
}

11.3. 그 이외의 연산자 오버로딩

...

Table of contents


Open source project on GitHub


Jupyter/IPython Notebook


Open API


NoSQL


Jekyll


Gradle


Kotlin


C++

  • C++ keywords
  • 윤성우 열혈강의 C++ 프로그래밍 예제코드 [펼치기]
    1. C언어 기반의 C++ 1
      • printf와 scanf를 대신하는 입출력 방식
      • 함수 오버로딩(Function Overloading)
      • 매개변수의 디폴트 값(Default Value)
      • 인라인 함수(Inline)함수
      • 이름공간(namespace)에 대한 소개
    2. C언어 기반의 C++ 2
      • 새로운 자료형 bool
      • 참조자(Reference)의 이해
      • 참조자(Reference)와 함수
      • maloc & free를 대신하는 new & delete
      • C++에서 C언어의 표준함수 호출하기
    3. 클래스의 기본
      • C++에서의 구조체
      • 클래스(Class)와 객체(Object)
      • 객체지향 프로그래밍의 이해
    4. 클래스의 완성
      • 정보은닉(Information Hiding)
      • 캡슐화(Encapsulation)
      • 생성자(Constructor)와 소멸자(Destructor)
      • 클래스와 배열 그리고 this 포인터
    5. 복사 생성자
      • ‘복사 생성자’ 와의 첫 만남
      • ‘깊은 복사’와 ‘얕은 복사’
      • 복사 생성자의 호출시점
    6. friend와 static 그리고 const
      • const와 관련해서 아직 못다한 이야기
      • 클래스와 함수에 대한 friend 선언
      • C++에서의 static
    7. 상속(Inheritance)의 이해
      • 상속에 들어가기에 앞서
      • 상속의 문법적인 이해
      • protected 선언과 세 가지 형태의 상속
      • 상속을 위한 조건
    8. 상속과 다형성
      • 객체 포인터의 참조관계
      • 가상함수(Vitual Function)
      • 가상 소멸자와 참조자의 참조 가능성
    9. 가상(Virtual)의 원리와 다중상속
      • 멤버함수와 가상함수의 동작원리
      • 다중상속(Multiple Inheritance)에 대한 이해
    10. 연산자 오버로딩 1
      • 연산자 오버로딩의 이해와 유형
      • 단항 연산자의 오버로딩의
      • 교환법칙 문제의 해결
      • cout, cin 그리고 endl의 정체
    11. 연산자 오버로딩 2
      • 반드시 해야 하는 대입 연산자의 오버로딩
      • 배열의 인덱스 연산자 오버로딩
      • 그 이외의 연산자 오버로딩
    12. String 클래스의 디자인
      • C++ 표준과 표즌 string 클래스
      • 문자열 처리 클래스의 정의
    13. 템플릿(Template) 1
      • 템플릿(Template)에 대한 이해와 함수 템플릿
      • 클래스 템플릿(Class Temlpate)
    14. 템플릿(Template) 2
      • Chapter 13에서 공부한 내용의 확장
      • 클래스 템플릿의 특수화(Class Temlpate Specialization)
      • 템플릿의 인자
      • 템플릿과 static
    15. 예외처리(Exception Handling)
      • 예외상황과 예외처리의 이해
      • C++의 예외처리 메커니즘
      • Stack Unwinding(스택 풀기)
      • 예외상황을 표현하는 예외 클래스의 설계
      • 예외처리와 관련된 또 다른 특성들
    16. C++의 형 변환 연산자
      • C++에서의 형 변환 연산

ETC