Steady Blog
22. 연산자 오버로딩 - 정리 필요. 본문
*연산자 오버로딩
1. 왜?
일반 변수처럼 클래스변수도 연산자를 사용하여 연산을 시키고 싶어서.
2. 어떻게?
operator() 함수를 사용해서
*operator() 함수
- 특수 함수
- 함수명 = operator
- 매개 변수의 갯수가 고정
1) 맴버함수 : 단항(0개), 이항(1개)
2) friend 함수 : 단항(1개), 이항(2개)
*friend 함수 - 전역함수.
1. 멤버 함수가 아님
2. 전역 함수
3. 매개변수로 클래스 변수를 가짐
그 클래스 변수(객체)를 통해서 멤버변수에 값을 대조하거나 바꿈.
연산자 오버로딩.
1. 연산자의 오버로딩
ㅊ++은 함수만 오버로딩이 되는 것이 아니다 연산자도 오버로딩이 가능하다
ㅊ++언어의 확장성을 증가시키고 자연스럽게 프로그램을 표현할수 있게 하기 위해 사용한다.
선언 방법은 일반 맴버 함수와 같다.
연산자 중복 정의 할수 없는 연산자..
::
->
?; 삼항 연산자는 안됨.
연산자 특징 - 특징이 많음 정리 필요.
1) c++언어에서 기본 자료 형에서 사용하고 있는 연산자를 의미를 변경하여 재정의 하는 것을 말한다.
2. 기존 c언어의 연산자들 사용하지 않으면 에러가 발생한다.
3) ㅊ++언어에서는 연산자를 함수로 취급하므로 연산자 오버로딩 방법은 함수 정의 방법과 동일하다.
4) 연산자 정의시 전달인자의 자료형에 의해 그 연산자를 사용할수 있는 자료형이 결정된다.
연산자 오버로딩 선언시 주의 사항.
class AAA
{
int x,y,z;
public:
void set(int a, int b)
{
x = a, y = b;
}
int add(int c)
{
return x+c;
}
friend int operator+(AAA m, int c) //friend 함수로 바꿈
{
return m.x+c; //friend 함수로 바꿈
}
};
void ch11_01()
{
AAA M;
M.set(10,20);
cout<<M.add(100)<<endl;
cout<<M.operator+(100)<<endl; // operator+ == +과 같은 거임.
cout<<M + 100 <<endl; // M.operator+(100)이라고 번역함. 즉, operator 함수 호출식
// 1) M.operator+(100)으로 번역
// 2) operator+(M,100)으로 번역 (friend 함수로)
}
// M+100 번역
1) M.operator+(100)으로 번역
2) operator+(M,100)으로 번역 => 100+M을 쓸려고 할때 사용함.
<연습 예제>
*복사생성자를 이용한 연산자 오버로딩
class Complex
{
int real, image;
public:
Complex() {real = image = 0;}
Complex(int rr, int ii);
void prn();
Complex operator+(Complex second);
};
Complex::Complex(int rr,int ii)
{
real = rr, image = ii;
}
void Complex::prn()
{
cout<<"("<<real<<" , "<<image<<")"<<endl;
}
Complex Complex::operator+(Complex second)
{
Complex res;
res.real = this->real + second.real;
res.image = this->image +second.image;
return res;
}
void ch11_03()
{
Complex x(10,20), y(20,40);
Complex z1;
z1= x+y; //연산자 우선순위에 의해 +붙어 실행. 즉 x.operator+(y) 실행.
x.prn();
y.prn();
cout<<"\n[z1 = x + y 결과] \n";
z1.prn();
Complex z2;
z2 = x.operator +(y);
cout<<"\n[z2 = x + y 결과] \n";
z2.prn();
}
<연습 예제>
*단항 연산자
class Counter
{
int value;
public:
Counter() {value = 0;}
Counter(int n) {value = n;}
int val(){return value;}
void operator++(){++value;}
void operator--(){--value;}
// friend 함수로 구현!
// friend void operator++(Counter &A){A.value++;}
// friend void operator--(Counter &A){--A.value;}
};
void ch11_04()
{
Counter ob1(10),ob2;
++ob1; //1) ob.operator++()를 먼저 찾음. 2) friend 함수 호출 즉, operator++(ob1)
--ob2; // 위와 같음.
cout<<"ob1 : "<<ob1.val()<<endl;
cout<<"ob2 : "<<ob2.val()<<endl;
ob1++;
ob2--;
cout<<"ob1 : "<<ob1.val()<<endl;
cout<<"ob2 : "<<ob2.val()<<endl;
}
<연습 예제>
operator 오버로딩 - 문제는 쉬우나 임시 변수를 모르면 어려운 예제.
class Point2
{
int xp, yp;
public:
Point2() {xp=yp=0;}
Point2(int x, int y) {xp = x, yp = y;}
void get_xy(int &x, int &y) {x = xp, y = yp;}
Point2 operator-(Point2 ob);
Point2 operator-();
};
Point2 Point2::operator -(Point2 ob)
{
Point2 tmp;
tmp.xp = xp - ob.xp;
tmp.yp = yp - ob.yp;
return tmp;
}
Point2 Point2::operator -()
{
xp = -xp;
yp = -yp;
return *this; // this == &p1; 즉, 호출한 p1자신을 return 하는 것.
}
void ch11_05()
{
Point2 p1(10,20), p2;
int x,y;
(p1-p2).get_xy(x,y); //p1-p2 => p1.operator-(p2) 이항 연산자
cout<<"[p1-p2 객체] x값 : "<<x<<", y값 : "<<y<<endl;
(-p1).get_xy(x,y); //-p1 => p1.operator-() 단항 연산자
cout<<"[-p1 객체] x값 : "<<x<<", y값 : "<<y<<endl;
}
<연습 문제>
class Opplus
{
int a;
public:
Opplus(){a=0;}
Opplus(int a1){a=a1;}
int get_data();
Opplus operator+(Opplus a);
Opplus operator-(Opplus a);
Opplus operator*(Opplus a);
Opplus operator/(Opplus a);
};
int Opplus::get_data()
{
return a;
}
Opplus Opplus::operator +(Opplus b)
{
b.a = a+b.a;
return b;
}
Opplus Opplus::operator -(Opplus b)
{
b.a = a-b.a;
return b;
}
Opplus Opplus::operator *(Opplus b)
{
b.a = a*b.a;
return b;
}
Opplus Opplus::operator /(Opplus b)
{
b.a = a/b.a;
return b;
}
void ch11_test()
{
Opplus ob1(10),ob2(5),ob3;
ob3 = ob1+ob2;
cout<<"ob1+ ob2= "<<ob3.get_data()<<endl;
ob3 = ob1-ob2;
cout<<"ob1- ob2= "<<ob3.get_data()<<endl;
ob3 = ob1*ob2;
cout<<"ob1* ob2= "<<ob3.get_data()<<endl;
ob3 = ob1/ob2;
cout<<"ob1/ ob2= "<<ob3.get_data()<<endl;
}
class Cstring
{
char abc[255];
public:
Cstring (char *a = "")
{
strcpy(abc,a);
}
char* getStr()
{
return abc;
}
void operator=(Cstring a)
{
strcpy(abc,a.abc);
}
/*
Cstring& operator=(Cstring &r) //str1=str2=str3 같은 것을 수행하기 위해 래퍼런스를 사용함.
{ // 즉, 디폴트 대입연산자 때문이다.
strcpy(abc,a.abc);
return *this;
}
*/
};
void ch11_test1()
{
Cstring str1("I like you.");
Cstring str2;
str2 = str1;
cout<<str1.getStr()<<endl;
cout<<str2.getStr()<<endl;
}
C++에서 디폴트가 사용되는 것들.
1. 디폴트 생성자
2. 디폴트 소멸자
3. 디촐트 복사 생성자
4. 디폴트 대입 연산자
'Programing > C++' 카테고리의 다른 글
23. 예외 처리 (0) | 2012.09.04 |
---|---|
21. 상속 part 2 ---정리 필요함. (0) | 2012.09.04 |
20. 상속 (0) | 2012.09.04 |
19. 정적변수 (0) | 2012.09.04 |
18. const변수 (0) | 2012.09.04 |