1. 필요성- 기존의 구조체(사용자 정의 자료형)는 사칙연산이 불가능 합니다.
- 클래스도 일종의 사용자 정의 자료형이라고 볼 수 있습니다.
- 그러므로 연산자 오버로딩을 통해 연산이 가능하도록 할 수 있습니다.
2. 연산자 오버로딩 형식- operator(keyword)- 같은 클래스 형태인 p1, p2로 정의 되었을경우 p1 = p2는 얕은 복사 만 이루어진다.
- 선언하는 방법(2가지) : 멤버함수, 전역함수의 형태로 만들어 볼 수 있습니다.
3. 호출 과정- p1 + p2;
- 첫번째. operator+를 찾습니다. 아래 두가지 방법으로 함수를 불러옵니다.
- 멤버함수의 경우. 왼쪽은 호출, 오른쪽은 인자
(p1.operator+(p2);)로 설정하여 함수를 불러옵니다.
-
전역함수의 경우. operator(p1, p2);로 선언되어 사용된다.
4. 왜 friend 전역함수와 멤버함수로 나눠서 선언해주어야 할까요?- p1 + p2가 만약 연산자 오버로딩에 의해 호출된다고 가정할 경우
- 첫번째 형태로 p1.operator+(p2)이런식으로 보통 정의 되어있을 것입니다.
이럴경우 p1이 당연히 operator+가 선언된 클래스의 일부가 되어야만
형식이 성립된다고 볼 수 있습니다.
- 그러나
p1이 operator+가 선언된 클래스의 형태가 아닌경우에는 p1.operator+(p2)형식이
성립이되지 않으므로 다른 형태로 선언해주어야 모든 조건을 수용할 수 있는
연산자 오버로딩을 이루어 낼 수 있을 것입니다.
5. 리턴의 참조- ++(++p)일 경우 기본은 ++p가 먼저 실행, ++(++P)가 실행되어야 합니다.
- ++(++p); -> ++(p.operator++())으로 변경
- p.operator++()가 리턴하는 경우(p,&p)
- p를 리턴 : p의 복사본을 리턴합니다. 그러므로 p를 다시 불러오면 변경되지 않았던 클래스가 다시 적용됩니다. (무한 반복이 일어납니다.)
- p&를 리턴할 경우 : 참조로 지정하기 때문에 p클래스 자체를 변경하여 리턴됩니다.
그러므로 변경된 클래스를 다시 컨트롤 할 수 있습니다.
6. p++일 경우 p.operator++(int)로 변경되어 미리 복사되어 연산하고 ++연산를
나중에 한다.- 아무 변수명 없이 (int)라고 선언해주면 됩니다.
7. 연산자의 교환법칙는?-
전역함수로 구현합니다.
ex) int형 정수와 클래스와 +연산의 경우
클래스가 먼저오면 p1.operator+(int a);가 가능하지만 int형 정수가 먼저오면 int a.operator(p1)이
불가능하므로 불가능한 부분만 변경해주면 됩니다.
Point operator+(int val, point &p){
Point temp(p.x+val, p.y+val)
}
8. 인덱스 연산자- arr.operator[i]는 문법상 불가능합니다.
- 그러므로
arr.operator[](i)로 약속하여 사용합시다.
9. 클래스를 출력하기 위해서는 cout 오버로딩 하여 사용해야함10.대입연산자의 deep copy- 사용하고 있던 메모리를 우선 해제(delete name[])
- 메모리 설정(new namea[strlen(p.name)+1])
- 직접 복사한다(strcpy(name, p.name)\
11. str1+str2는 새로운공간 필요, str1 += str2는 기존의 공간을 포인터를 이용하여 적용
예제)