friend 함수에 의한 연산자 재정의
1
멤버 함수를 이용하여 연산자를 재정의할 경우 왼 쪽 자료 (1st operand) 는
반드시 연산자가 재정의된 클래스의 객체이어야 함
friend 함수를 이용하여 연산자를 재정의하면
왼 쪽 자료 (1st operand) 의 자료형에 제약을 두지 않고 사용할 수 있게 할 수 있음
단 , = 은 friend 함수로 재정의 할 수 없음
[1] 이항 연산자 재정의 class className {
friend className operator operaorSymbol(type1, type2, . . .);
};
className operator operaorSymbol(parameter1, parameter2, . . .)
{
문장 ( 들 ) ∙ ∙ ∙
return(objectName);
}; - operatorSymbol : 기존의 연산자 (+, -, *, /, %, ++, --, 기타 ) 주의 : friend 함수로 = 연산자는 재정의 할 수 없다 .
- return 값 : 객체 등 필요한 자료
-실행 시 연산자의 왼쪽 피연산자 (1st operand) 는 parameter1 으로 ,
오른쪽 피연산자 (2nd operand) 는 parameter2 에
call by value 로 전달되어 처리된다 .
3
( 예 ) 이항 연산자 재정의 : (class+class), (class+int), (int+class)
/*001*/ // operatorOverloading52 : with friend function /*002*/
/*003*/ #include <iostream>
/*004*/ using namespace std;
/*005*/ class overloadingClass /*006*/ {
/*007*/ private: int x, y, z;
/*008*/ public:
/*009*/ overloadingClass(int px=0, int py=0, int pz=0) /*010*/ {x = px; y = py; z = pz;};
/*011*/
/*012*/ void coutMemberData()
/*013*/ {cout << "\n x=> " << x << "\n y=> " << y << "\n z=> " << z;};
/*014*/
/*015*/ overloadingClass operator =(overloadingClass operand2);
/*016*/
/*017*/ friend overloadingClass operator +(overloadingClass operand1,
/*018*/ overloadingClass operand2);
/*019*/ friend overloadingClass operator +(overloadingClass operand1,
/*020*/ int operand2);
/*021*/ friend overloadingClass operator +(int operand1,
/*022*/ overloadingClass operand2);
/*023*/ };
/*024*/ overloadingClass overloadingClass::operator
=(overloadingClass
operand2) /*025*/ {
/*026*/ this->x = operand2.x;
/*027*/ this->y = operand2.y;
/*028*/ this->z = operand2.z;
/*029*/ return *this;
/*030*/ };
5
/*031*/ overloadingClass operator +(overloadingClass operand1, /*032*/ overloadingClass operand2) /*033*/ {
/*034*/ operand2.x = operand1.x + operand2.x;
/*035*/ operand2.y = operand1.y + operand2.y;
/*036*/ operand2.z = operand1.z + operand2.z;
/*037*/ return operand2;
/*038*/ };
/*039*/ overloadingClass operator +(overloadingClass operand1, int operand2)
/*040*/ {
/*041*/ operand1.x = operand1.x + operand2;
/*042*/ operand1.y = operand1.y + operand2;
/*043*/ operand1.z = operand1.z + operand2;
/*044*/ return operand1;
/*045*/ };
/*046*/ overloadingClass operator +(int operand1, overloadingClass operand2)
/*047*/ {
/*048*/ operand2.x = operand1 + operand2.x;
/*049*/ operand2.y = operand1 + operand2.y;
/*050*/ operand2.z = operand1 + operand2.z;
/*051*/ return operand2;
/*052*/ };
/*053*/
/*054*/ void main() /*055*/ {
/*056*/ overloadingClass A(10, 20, 30);
/*057*/ overloadingClass B(1, 2, 3);
/*058*/ overloadingClass X;
/*059*/
/*060*/ X = A + B;
/*061*/ cout << " values in X after X = A + B;";
/*062*/ X.coutMemberData();
/*063*/
/*064*/ X = A + 55;
/*065*/ cout << "\n\n values in X after X = A + 55;";
/*066*/ X.coutMemberData();
/*067*/
/*068*/ X = 66 + A;
/*069*/ cout << "\n\n values in X after X = 66 + A;";
/*070*/ X.coutMemberData();
/*071*/
/*072*/ char x;
/*073*/ cout << "\n\n\n Good bye...\n Type any characte<Enter>: ";
/*074*/ cin >> x;
/*075*/ }
7
/*017*/ friend overloadingClass operator +(overloadingClass operand1, /*018*/ overloadingClass operand2);
(overloadingClass + overloadingClass) 를 처리하는 함수를 friend 로 선언한다 .
/*019*/ friend overloadingClass operator +(overloadingClass operand1, /*020*/ int operand2);
(overloadingClass + int) 를 처리하는 함수를 friend 로 선언한다 . /*021*/ friend overloadingClass operator +(int operand1,
/*022*/ overloadingClass operand2);
(int + overloadingClass) 를 처리하는 함수를 friend 로 선언한다 .
/*031*/ overloadingClass operator +(overloadingClass operand1, /*032*/ overloadingClass operand2)
/*033*/ {
/*034*/ operand2.x = operand1.x + operand2.x;
/*035*/ operand2.y = operand1.y + operand2.y;
/*036*/ operand2.z = operand1.z + operand2.z;
/*037*/ return operand2;
/*038*/ };
(overloadingClass + overloadingClass) 를 처리하는 함수를 정의한다 .
/*039*/ overloadingClass operator +(overloadingClass operand1, int operand2) /*040*/ {
/*041*/ operand1.x = operand1.x + operand2;
/*042*/ operand1.y = operand1.y + operand2;
/*043*/ operand1.z = operand1.z + operand2;
/*044*/ return operand1;
/*045*/ };
(overloadingClass + int) 를 처리하는 함수를 정의한다 .
/*046*/ overloadingClass operator +(int operand1, overloadingClass operand2) /*047*/ {
/*048*/ operand2.x = operand1 + operand2.x;
/*049*/ operand2.y = operand1 + operand2.y;
/*050*/ operand2.z = operand1 + operand2.z;
/*051*/ return operand2;
/*052*/ };
(int + overloadingClass) 를 처리하는 함수를 정의한다 .
9
/*056*/ overloadingClass A(10, 20, 30);
/*057*/ overloadingClass B(1, 2, 3);
/*058*/ overloadingClass X;
overloadingClass 형의 객체 A, B, 그리고 X 를 생성한다 . /*060*/ X = A + B;
A 와 B 모두 overloadingClass 형이므로 /*031*/ 의 + 가 선택되어 수행된다 . /*064*/ X = A + 55;
A 는 overloadingClass 형 , 55 는 int 형이므로 /*039*/ 의 + 가 선택되어 수행된다 . /*068*/ X = 66 + A;
66 은 int 형이고 A 는 overloadingClass 이므로 /*046*/ 의 + 가 선택되어 수행된다 .
[ 결과 ]
11
[2] 일항 연산자 재정의
(1) prefix ++, -- 의 재정의 class className
{
friend className operator ++(className ¶meter);
friend className operator --(className ¶meter);
};
className operator ++(className ¶meter) className operator --(className ¶meter) {
문장 ( 들 );
return 객체 ;
};
(2) postfix ++, -- 의 재정의 class className
{
friend className operator ++(className ¶meter, int no);
friend className operator --(className ¶meter, int no);
};
className operator ++(className ¶meter, int no) className operator --(className ¶meter, int no) {
문장 ( 들 );
return 객체 ;
13
( 예 ) 일항 연산자 재정의 : prefix ++, --, postfix ++, --
/*001*/ // operatorOverloading60 : with frind function /*002*/ // unary operator(++, --)
/*003*/
/*004*/ #include <iostream>
/*005*/ using namespace std;
/*006*/ class operationClass /*007*/ {
/*008*/ private: int value;
/*009*/
/*010*/ public:
/*011*/ operationClass() /*012*/ {
/*013*/ this->value = 0;
/*014*/ } /*015*/
/*016*/ void coutMemberData() /*017*/ {
/*018*/ cout << "value=> " << value;
/*019*/ } /*020*/
/*021*/ friend operationClass operator ++(operationClass &add30);
/*022*/ friend operationClass operator --(operationClass &minus1);
/*023*/ friend operationClass operator ++(operationClass &add70, int no);
/*024*/ friend operationClass operator --(operationClass
&minus11, int no);
/*025*/ };
/*026*/
SQ Lab. 15
/*027*/ operationClass operator ++(operationClass &add30) //prefix ++
/*028*/ {
/*029*/ add30.value = add30.value + 30;
/*030*/ return add30;
/*031*/ };
/*032*/
/*033*/ operationClass operator --(operationClass &minus1) //prefix --
/*034*/ {
/*035*/ minus1.value = minus1.value - 1;
/*036*/ return minus1;
/*037*/ };
/*038*/
/*039*/ operationClass operator ++(operationClass &add70, int no) //
postfix ++/*040*/ {
/*041*/ add70.value = add70.value + 70;
/*042*/ return add70;
/*043*/ };
/*044*/
/*045*/ operationClass operator --(operationClass &minus11, int no) //
postfix --/*046*/ {
/*047*/ minus11.value = minus11.value - 11;
/*048*/ return minus11;
/*049*/ };
/*050*/
/*051*/ void main() /*052*/ {
/*053*/ operationClass operation;
/*054*/
/*055*/ cout << "\n initial ";
/*056*/ operation.coutMemberData();
/*057*/
/*058*/ ++operation;
/*059*/ cout << "\n\n ++operation; ";
/*060*/ operation.coutMemberData();
/*061*/
/*062*/ --operation;
/*063*/ cout << "\n\n --operation; ";
/*064*/ operation.coutMemberData();
/*065*/
/*066*/ operation++;
/*067*/ cout << "\n\n operation++; ";
/*068*/ operation.coutMemberData();
/*069*/
/*070*/ operation--;
/*071*/ cout << "\n\n operation--; ";
17
/*073*/
/*074*/ char x;
/*075*/ cout << "\n\n\n Good bye...\n Type any characte<Enter>: ";
/*076*/ cin >> x;
/*077*/ }
/*006*/ class operationClass 클래스 operationClass 를 정의한다 . /*007*/ {
/*008*/ private: int value;
private 정수형 멤버자료 value 를 정의하였다 . /*010*/ public:
/*011*/ operationClass() /*012*/ {
/*013*/ this->value = 0;
/*014*/ }
value 에 0 을 수록하는 생성자를 정의하였다 . /*016*/ void coutMemberData() /*017*/ {
/*018*/ cout << "value=> " << value;
/*019*/ }
value 의 값을 출력하는 coutMemberDatat() 를 정의하였다 .
19
/*021*/ friend operationClass operator ++(operationClass &add30);
/*022*/ friend operationClass operator --(operationClass &minus1);
/*023*/ friend operationClass operator ++(operationClass &add70, int no);
/*024*/ friend operationClass operator --(operationClass &minus11, int no);
prefix ++, --, postfix ++, -- 를 재정의하는 함수를 friend 로 선언하였다 . /*025*/ };
/*027*/ operationClass operator ++(operationClass &add30) //prefix ++
prefix 로 처리되는 ++ 연산자를 재정의한다 .
형식인자를 operationClass 형의 객체 add30 이며 call by refernce 로 처리된다 . /*028*/ {
/*029*/ add30.value = add30.value + 30;
add30 의 value 에 30 을 누적한다 . /*030*/ return add30;
add30 을 리턴한다 . /*031*/ };
/*033*/ operationClass operator --(operationClass &minus1) //prefix -- prefix 로 처리되는 -- 연산자를 재정의한다 .
형식인자를 operationClass 형의 객체 minus1 이며 call by refernce 로 처리된다 . /*034*/ {
/*035*/ minus1.value = minus1.value - 1;
minus1 의 value 에 1 을 감소한다 . /*036*/ return minus1;
minus1 을 리턴한다 . /*037*/ };
21
/*039*/ operationClass operator ++(operationClass &add70, int no) //postfix ++
postfix 로 처리되는 ++ 연산자를 재정의한다 .
형식인자를 operationClass 형의 객체 add70 이며 call by refernce 로 처리된다 . /*040*/ {
/*041*/ add70.value = add70.value + 70;
add70 의 value 에 70 을 누적한다 . /*042*/ return add70;
add70 을 리턴한다 . /*043*/ };
/*045*/ operationClass operator --(operationClass &minus11, int no) //postfix -- postfix 로 처리되는 -- 연산자를 재정의한다 .
형식인자를 operationClass 형의 객체 minus11 이며 call by refernce 로 처리된다 . /*046*/ {
/*047*/ minus11.value = minus11.value - 11;
minus11 의 value 에 11 을 감소한다 . /*048*/ return minus11;
minus11 을 리턴한다 . /*049*/ };
/*053*/ operationClass operation;
operationClass 형의 객체 operation 을 생성한다 . /*058*/ ++operation;
위의 문장은 실인자를 operation 으로 하여 ++() 함수를 호출하는 개념이다 . 즉 ++(operation); 로 해석된다 .
++ 가 prefix 로 사용되었으므로 /*027*/ 이 선택되어 수행된다 . /*062*/ --operation;
위의 문장도 실인자를 operation 으로 하여 --() 함수를 호출하는 개념이다 . 즉 --(operation); 로 해석된다 .
-- 가 prefix 로 사용되었으므로 /*033*/ 이 선택되어 수행된다 . /*066*/ operation++;
위의 문장은 실인자를 operation 으로 하여 ++() 함수를 호출하는 개념이다 . 즉 ++(operation); 로 해석된다 .
++ 가 postfix 로 사용되었으므로 /*039*/ 가 선택되어 수행된다 . /*070*/ operation--;
위의 문장도 실인자를 operation 으로 하여 ++() 함수를 호출하는 개념이다 . 즉 ++(operation); 로 해석된다 .
++ 가 postfix 로 사용되었으므로 /*045*/ 가 선택되어 수행된다 .
23