● 저번주 내용
■ 함수중첩
■ 생성자 중첩
■ 디폴트 인자
● 이번주 내용
■ 연산자중첩
■ 단항 연산자 중첩
■ 전치 , 후치
■ 이항 연산자 중첩
■ 형변환 함수
연산자 중첩 (operator overloading)
● 연산자 오버로딩
● 다형성을 구현하는 방법 중 하나
● 기존에 사용하고 있는 연산자(+, -, *, /, =, %, ++, <, !, +=, <<, ==, &&, &, [ ], ( ), "," , -> 등)의
기능을 클래스에서 새롭게 정의하여 사용하는 것
● 주로 숫자나 문자를 대상으로 하는 연산자들을 해당 클래스에서는 재정의하여 사용자들에게
편리한 프로그래밍을 제공
연산자의 개념과 종류
● 연산자(operator)는 변수 또는 상수에 대하여 무엇인가를 행하도록 하는 단어나 기호
● 피연산자(operand)는 연산자가 연산을 하는 대상
● 피연산자의 수에 따라서 다음과 같이 구분
● (), [], 콤마, *, =같은 연산자는 쓰이는 위치에 따라서 구두점일 수도 있음
연산자의 우선순위
● 한 수식에 연산자들이 여러 개 있을 때 우선순위가 제일 높은 것은 괄호 안의 수식
● 괄호들이 중첩되어 있을 때는 내부 괄호가 우선순위가 높음
● 사칙연산은 * , /, 그 다음이 +, -이며 우선순위가 같으면
다음과 같이 왼쪽에서 오른쪽으로 연산을 진행
● 대입 연산자(=, +=, -= 등)는 오른쪽에서 왼쪽으로 실행
● x=a*b
■ a*b한 결과를 x에 대입하는 것으로 오른쪽에서 왼쪽으로 실행
● 괄호 연산자(())가 우선순위가 가장 높고, 콤마 연산자가(,)가 가장 낮음
C언어 연산자의 우선순위와 결합성
결합성 : 우선순위가 같은 연산자의 결합 방향을 의미함 (결합성쪽의 화살표 방향 제대로 확인)
참고에 도움이 될수 있는 자료들 (영어 주의)
↓ Operators in C and C++ : 우선순위와 결합방향 ↓
https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
↓ Operator overloading : 연산자 중첩 ↓
https://en.wikipedia.org/wiki/Operator_overloading
연산자 중첩의 필요성
■ i+j라는 식은 두 자료 i와 j를 더하라는 의미
■ 일반적으로 i와 j는 같은 형으로 int형, float형, double형 수이다.
■ 10+20, 12.5+3.7 등
■ i와 j가 문자열(i="I Love", j="You!" )이라면 i+j는 C에서는 불가능
■ C에서는 strcat함수로 다음과 같이 구현한다.
■ 2차원 좌표계의 한 점을 표현하는 경우 (2, 3), (3, 4) 등으로 x좌표값과 y좌표값으로 표현한다.
■ 수학에서는 (2, 3)+(3, 4) 하면 각 성분끼리 더해져서 (5, 7)이된 된다.
■ 프로그래밍에서 사용하는 "+"연산자에 이러한 기능은 없다.
■ +연산자가 다양한 덧셈에 사용 가능하도록 연산자의 의미를 확대 재정의하는 방법이 연산자 중첩
■ 더한다는 의미의 연산은 모두 “+”연산자 하나로 구현
연산자 중첩 방식
● 연산자 중첩은 클래스 안에서 연산자의 의미를 변경시킴으로써 객체와 객체사이의 연산에서
사용자가 원하는 연산을 하도록 한다.
● operator라는 키워드를 사용하며, 그 형식은 다음과 같다.
● 단항연산자 중첩
● 리턴형 operator 연산자명(); //전치, ++x
● 리턴형 operator 연산자명(int); //후치, x++
● 이항연산자 중첩
● 리턴형 operator 연산자명(매개변수);
2차원 좌표계의 한점을 처리하는 Point 클래스
연산자 중첩을 사용하여 1씩 증가시키는 코드를 짜면 이렇습니다.
private형 int x , y 선언, 입력받는 수가 2개 이므로 public에도 i , j 선언
++x; , ++y;는 전치이므로 더하고 출력한다 (출력하고 난다음에 더하는건 후치)
void upPrint() 와 Point up() 함수에 전치 x,y연산이 들어가게 되는데 이들을 호출할때마다 x,y값이 1씩증가한다.
x와 y가 들어갈곳을 p1이라고 정하고 3,4를 입력하면up Print() 는 출력까지 자동으로 하므로 4,5가 출력되고up() 는 1씩 증가만 시키므로 추가적으로 출력코드를 작성해야 한다. (여기서 나오는건 5,6)
이제부터 본격적으로 연산자 중첩을 이용한 응용에 들어가봅시다.
(여기서부터 사람마다 상당히 헷갈릴수 있으니 천천히 이해하시는게 편합니다.)
11-1. 전치 단항 연산자 중첩
아까전에는 void를 이용해 직접 만든 함수로 진행했지만
이번엔 operator를 이용하여 연산자를 중첩한다 ( operator ++() 라고 쓰면 아까전의 p1.up과 같은 상태가 된다 )
1. Point p1 (2,3) = 포인트 리턴형을 p1로 설정하고 2,3을 선언하여 x,y에 대입한다.
2. operator에 ()가 [사실상 p1 대입된 상태] 선언되어 아까전처럼 괄호를 쓸 필요없이 ++p1;로 쓰면 된다.
3. *this가 리턴한 값을 getX , getY에 대입하고 호출한다.
11-1-2. 11-1 문항을 클래스 바깥에서 정의하기
전에서도 자세한 정보를 클래스 외부에서 정의 한것처럼 하면 된다.
point point :: operator ++() [이하는 같음]
11-2. 후치 단항 연산자 중첩
후치로 사용하는 경우에는 operator 괄호부분에 형 이름을 집어넣어줘야 한다.
쓰지 않으면 오류가 나서 실행이 중단된다. (미리 형을 정하는 전치 연산과 달리 후치는 연산후 형 이름을 따라가기 때문)
이항 연산자 중첩
■ 이항 연산자란 +, -, ×, ÷, % 등 연산자 양쪽에 피연산자가 필요한 연산자이다.
■ 이항 연산자 중첩에서는 한 개의 매개변수가 필요하다.
■ 연산자의 왼쪽 피연산자가 연산자 함수의 주체가 되고, 오른쪽 피연산자만 있으면 되기 때문이다.
■ 즉 "1+2" 라는 연산에서 왼쪽 피연산자 1이 "+"연산자의 주체이다.
■ 1+(2) //1이 연산자의 주체 , (2)가 매개변수
(이 부분은 특히 어지럽습니다 , 이해가 안되어도 천천히 보다보면 이해하실수 있으니 걱정안하셔도 됩니다 ^^)
11-3. 이항 연산자 중첩 +
int xx , int yy가 나와서 좀 당황스럽지만 사실은 별거 없습니다.
int main에 ob1 , ob2 , ob3가 있으니 하나씩 대입하면 됩니다. (ob3 자리는 없으니 0으로 자동 초기화)
(ob1은 첫번째 x,y자리에 ob2는 두번째 x,y자리에 이런식으로)
ex . ob1 ( 3 , 5 ) → int (3) x , int (5) y , ob2 ( 4 , 6 ) → int x (4) , int y (6)
operator는 함수이름이므로 x,y를 직접 써서 사용한다. (연산자의 주체와 매개변수를 파악할것)
클래스 내부에서 ob로 정의했으므로 당연히 더하는 매개변수도 ob로 시작해야 한다. (ob.x , ob.y)
[ point point::operator +(point ob) 부분 자세히 살펴볼것 ]
int main 함수 부분에서는 ob3이 입력받아 출력하라지만 초기화 후 받은게 없으니 당연히 0이 뜬다.
ob3 = ob1 + ob2 // 이부분이 이항 연산자가 사용되는 직접적인 부분이다.
// operator x,y 즉, ob1 연산자의 주체이며, ob2가 매개변수로 넘어온것이다.
11-4 클래스의 "*" 연산자 중첩
왜 return *this; 사용하면 주체인 ob1의 값이 바뀐다고 비추하는걸까?
실제로도 temp 방식을 써도 return *this를 써도 나오는건 둘다 정상적이고 잘 작동한다.
x = x*ob.x; 부분을 주목하자.
x(3) 에다가 4를 곱하면 12가 된는다건 누구나 다 안다, 여기서 하지만 치명적인 문제가 있다.
return *this 때문에 12 그대로 넘겨버린다는것, 즉 x가 영구적으로 12가 되어버린것과 같다.
( y도 영구적으로 30이 되어버린다. )
나중에 연산할때는 x가 12가 되어버린채로 연산하기 때문에 비추천 하는것이다. (그대로 넘겨버리기에)
11-5. point 클래스의 "==" 연산자 중첩
비교하는 부분에서만 알아보고 가자면,
return ( x == ob.x && y == ob.y) ? 'T' : 'F'; // 같으면 T, 다르면 F
즉, 비교하고자하는 두개의 값이 각각 같은가를 물어보는것이다.
ob1 과 ob2는 x,y값이 각각 다르므로 F가 나오고, ob1 과 ob3는 x,y값이 각각 같으므로 T가 나온다.
//괄호로 감싸주지 않으면, 이러한 피연산자와 일치하는 "<<"연산자가 없다고 뜨며, 에러가 난다.
형변환 함수 ( type conversion function )
● 한 객체의 자료형을 다른 객체의 자료형으로 변환시키고자 할 때 형변환 함수(type conversion function)를 이용한다.
● operator 리턴형() {return 변환값;}
● 리턴형은 변환하고자 하는 자료형이고 변환값은 변환을 수행할 값이다.
● 형변환 함수는 매개변수를 갖지 않으며 형변환을 수행하는 클래스의 멤버함수이어야 한다.
11-6. 형변환 함수
i=ob1을 수행하면 i가 정수형이므로 Point형의 객체 ob1이 정수형으로 변환되고,
(리턴형이 *연산자이므로) 변환함수 int를 실행하여 3*5의 값이 i에 저장된다.
즉, ( 3 , 5 ) 가 아닌 ( 3 * 5 )가 된것이다.
ob2+6을 수행하면 int변환함수를 호출하여 (+6 이라는 정수형 덧셈이 존재하므로)
Point형의 객체 ob2가 4*6의 정수형으로 변환된 후 덧셈을 한다.
연산자 중첩의 제약
■ 모든 연산자가 중첩될 수 있는 것은 아니다.
■ 다음 연산자들은 중첩이 불가능하다.
■ . .* ::
■ 이 연산자들은 첫 번째 피연산자로 그 객체를 갖는다는 미리 정의된 의미를 가지므로
(.*는 멤버 포인터 연산자)
■ ?: sizeof
■ 이 연산자들은 중첩이 필요 없다고 생각하므로
연산자 중첩시 주의사항
● 우선 순위를 변경할 수 없다.
● 단항 연산자를 다항 연산자로 변경할 수 없다.
● 임의의 새로운 연산자(**, <>)를 정의할 수 없다.
● operator+()와 operator=()를 정의했다고 해서 operator+=()이 정의되지는 않는다.
● 기본 자료형(int, char, float 등)에 대해서는 중첩을 허용하지 않는다.
● "=" 연산자를 제외하고, 연산자는 파생(자식) 클래스에 상속된다.
해당 내용은 인덕대학교 2021년도 2학기 C프로그래밍 한성현 교수님 강좌에서 발췌한 내용입니다.
강좌 내용을 원저작자 허락없이 무단 이용시, 처벌의 대상이 될수 있습니다.
'C > C++' 카테고리의 다른 글
C++ (13주) [상속 2 , 가상 함수] (0) | 2022.10.19 |
---|---|
C++ (12주) [상속 1] (0) | 2022.10.15 |
C++ (10주) [ 함수 중첩 , 디폴트 인자 ] (0) | 2022.10.01 |
C++ (9주) [const , new , delete] (2) | 2022.10.01 |
C++ (8-3주) 중간고사 정리 3 (0) | 2022.09.19 |
댓글