Transcript 강의10

Chapter 10. 11. 연산자 오버로딩
Chapter 10-1. 연산자 오버로딩의 이해와 유형
연산자 오버로딩 (다중정의)
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0) : xpos(x), ypos(y) { }
void ShowPosition() {
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
.// 일부코드 생략 . . .
};
int main(void)
{
Point pos1(3, 4);
Point pos2(10, 20);
Point pos3=pos1+pos2;
pos1.ShowPosition();
pos2.ShowPosition();
pos3.ShowPosition();
return 0;
}
3
[3, 4]
[10, 20]
[13, 24]
연산자 오버로딩 (다중정의)
Point point1(3, 4);
Point point2(10, 20);
Point point3 = point1 + point2;
int num 3 + 4;
피연산자에 따라 연산자의 작동이 달라진다. – 연산자 오버로딩 (다중정의)
파라미터에 따라 함수의 작동이 달라진다. – 함수 오버로딩 (다중정의)
int add(int m, int n),
Complex add(Complex a, Complex b)
int k = add(1, 2);  k는 3
Complex c1(1, 2);  c1 = i + 2j
Complex c2(3, 4);  c2 = 2 + 4j
Complex c3 = add(i, j);  c3 = 3i + 6j
4
연산자를 오버로딩 하는 첫번째 방법
멤버함수 오버로딩
실행결과
5
연산자 오버로딩에서 이야기하는 함수호출의 규칙을 이해하는 것이 중요!
연산자를 오버로딩 하는 두번째 방법
오버로딩 형태에 따라서 스스로 변환!
전역함수 오버로딩
실행결과
6
Chapter 10-2. 단항 연산자 오버로딩
증가, 감소 연산자의 오버로딩
8
전위증가와 후위증가의 구분
멤버함수 형태의 후위 증가
전역함수 형태의 후위 감소
9
Chapter 11-1. 대입 연산자의 오버로딩
객체간 대입연산의 비밀: 디폴트 대입 연산자
복사 생성자의 호출
대입 연산자의 호출
pos2.operator=(pos1);
대입연산자 오버로딩 코드를 적어주지
않으면 기본(디폴트)대입연산자가 자
동으로 삽입된다.
멤버 대 멤버의 복사를 진행하는 디폴트 대입
연산자 삽입!
11
Frist 클래스의 디폴트 대입 연산자
대입연산를 직접 작성해야 하는 경우
포인터 타입 멤버변수를 가지고 있으며 깊은 복사가 필요한 경우
디폴트 복사생성자를 그냥 사용하지 않고 직접 복사생성자를 적어 넣어주어야 했던 경우와 동일!
실행결과
12
상속 구조에서의 대입 연산자 호출
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;
}
First& operator=()
111, 222
333, 444
};
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;
}
};
main {
Second ssrc(111, 222, 333, 444);
Second scpy(0, 0, 0, 0);
scpy = ssrc;
scpy.ShowData();
return 0;
디폴트 대입 연산자는 기초 클래스의 대입연산자를 호출해준다!
13
상속 구조에서의 대입 연산자 호출
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;
}
Second& operator=()
0, 0
333, 444
};
Second ssrc(111, 222, 333, 444);
Second scpy(0, 0, 0, 0);
scpy = ssrc;
scpy.ShowData();
return 0;
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;
num3=ref.num3;
num4=ref.num4;
return *this;
}
};
명시적으로 대입 연산자를 정의하는 경우에는 기초 클래스의 대입 연산자가 자동으로 호출되지 않는다!
14
상속 구조에서의 대입 연산자 호출
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;
}
First& operator=()
Second& operator=()
111, 222
333, 444
};
Second ssrc(111, 222, 333, 444);
Second scpy(0, 0, 0, 0);
scpy = ssrc;
scpy.ShowData();
return 0;
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;
}
};
명시적으로 대입연산자를 정의하는 경우에는 기초클래스의 대입 연산자를 명시적으로 호출해야 한다.
15
확인문제
C10-1

디폴트 복사생성자와 디폴트 대입연산자가 작동하는 예를 보이시오.
C10-2

디폴트 대입연산자가 얕은복사를 한다는 것을 보이는 예를 작성하시오.
C10-3

위의 얕은복사를 하는 예를 수정하여 깊은복사를 하도록 하시오.
C10-4

슈퍼클래스로부터 상속한 멤버변수를 갖는 서브클래스의 경우 디폴트 대입
연산자가 상속한 멤버변수를 포함한 모든 멤버변수를 복사한다는 것을 보이
는 예를 작성하시오.
C10-5

슈퍼클래스로부터 상속한 멤버변수를 가지며 포인터 변수를 갖는 서브클래
스의 예를 생각하여 깊은 복사가 이루어지도록 대입연산자를 작성하시오.
16
실습문제
P10-1

디폴트 복사생성자와 디폴트 대입연산자가 작동하는 예를 보이시오.
P10-2

디폴트 대입연산자가 얕은복사를 한다는 것을 보이는 예를 작성하시오.
P10-3

위의 얕은복사를 하는 예를 수정하여 깊은복사를 하도록 하시오.
P10-4

슈퍼클래스로부터 상속한 멤버변수를 갖는 서브클래스의 경우 디폴트 대입
연산자가 상속한 멤버변수를 포함한 모든 멤버변수를 복사한다는 것을 보이
는 예를 작성하시오.
P10-5

슈퍼클래스로부터 상속한 멤버변수를 가지며 포인터 변수를 갖는 서브클래
스의 예를 생각하여 깊은 복사가 이루어지도록 대입연산자를 작성하시오.
17
실습문제
P10-6
 p. 410 문제 3에 다음 연산자를 추가로 오버로딩하시오.

아래 두 연산자는 멤버함수를 이용하여 오버로딩



연산자 ‘pos1 < pos2’의 결과로 pos1의 크기가 pos2보다 작으면 true, 그렇지
않으면 false를 반환
아래 두 연순자는 전역함수를 이용하여 오버로딩



연산자 ‘pos1 > pos2’의 결과로 pos1의 크기가 pos2보다 크면 true, 그렇지 않
으면 false를 반환
연산자 ‘pos1 >= pos2’의 결과로 pos1의 크기가 pos2보다 크거나 같으면 true,
그렇지 않으면 false를 반환
연산자 ‘pos1 <= pos2’의 결과로 pos1의 크기가 pos2보다 작거나 같으면 true,
그렇지 않으면 false를 반환
단, Point의 크기는 다음과 같이 계산
pos1의 크 기 =
18
pos1. xpos  pos1. ypos
2
2
실습문제
P10-7

p. 418 문제 10-2를 변경하여 다음과 같은 단항 연산자를 오버로딩하고 실
행 예를 보이시오.


19
단항 연산자 ‘-’: 멤버 변수들의 부호가 모두 음수로 바뀐 새로운 객체를 만드어
반환 (기존 프로그램 수정)
단항 연산자 ‘+’: 멤버 변수들의 부호가 모두 ‘+’로 바뀐 새로운 객체를 만들어
반환 (새로 추가)

(예)

아래와 같이 하면 p2는 (-1, -2)의 멤버변수값을 갖는 Point 객체이어야 함

Point p = Point(1, -2);

Point p2 = -p;
실습문제
P10-8

p. 418 문제 10-2를 변경하여 다음과 같은 단항 연산자를 오버로딩하고 실
행 예를 보이시오.
20

단항 연산자 ‘++’: 멤버 변수들의 값이 2만큼 증가하고 객체자신을 반환

(예)

아래와 같이 하면 p는 (5, 6)의 멤버변수값을 갖는 Point 객체이어야 함

Point p = Point(1, 2);

++(++p);