Steady Blog

22. 연산자 오버로딩 - 정리 필요. 본문

Programing/C++

22. 연산자 오버로딩 - 정리 필요.

우유먹고쑥 2012. 9. 4. 00:03

*연산자 오버로딩

 

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