ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 연산자 오버로딩 (+대입연산자, 전위/후위연산자 )
    프로그래밍 언어/C++ 2024. 7. 3. 13:24
    1. 연산자 오버로딩 형태
    2. 대입 연산자             
    3. 전위/후위 연산자      

     

    연산자 오버로딩 형태

    [반환값]operator[연산자]([인자])
    ex) int operator+(const int& number)
    > int b = (int)a + 2;
    • 전역 연산자든 멤버함수 연산자 오버로딩이든 사용자 정의 연산자 정의이기에 클래스를 통해서 이뤄짐
      • int operator(int a, int b) {} // 컴파일러 오류
      • 기본 타입에 대한 전역 연산자 오버로딩의 경우 표준 라이브러리 호환성 유지를 위해 오류를 내보냄
    • 전역 연산자 오버로딩
      • [반환값]operator[연산자]([인자1], [인자2])
        • 인자1 : 왼쪽 피연산자
        • 인자2 : 오른쪽 피연산자
          • ex) 반환값 = a(왼쪽 피연산자) + b (오른쪽 피연산자)
            • 인자1 : a , 인자2 : b
    • 멤버함수 연산자 오버로딩
      • 해당 클래스 자기자신을 기준으로 인자값을 연산함
        • 왼쪽 피연산자가 자기자신이 아닌경우 -> 전역 연산자 오버로딩으로 매개변수 위치 설정
      • [반환값]operator[연산자]([인자])
        • 왼쪽피연산자는 자기자신
          •  
          • 클래스 자기자신 지칭 : *this
        • 인자 : 오른쪽 피연산자
      • ex) 반환값 = a(왼쪽 피연산자) + b (오른쪽 피연산자);
        • a : 클래스 자기 자신
        • b : 더해질 값 (클래스 , 상수 ...)
    class Position
    {
    public:
        //(0)
        //복사 대입 연산자
        Position& operator= (const Position& arg)
        {
    	    pos_x = arg.pos_x;
    	    pos_y = arg.pos_y;
    
    	    return *this;
        }
        
    	Position operator+ (const Position& pos2)
    	{
    		Position pos;
    		pos.pos_x = pos_x + pos2.pos_x;
    		pos.pos_y = pos_y + pos2.pos_y;
    		return pos;
    	}
    	
        // (1)
    	Position operator+ (int arg)
    	{
    		Position pos;
    		pos.pos_x = pos_x + arg;
    		pos.pos_y = pos_y + arg;
    		return pos;
    	}
    public:
    	int pos_x = 0;
    	int pos_y = 0;
    };
    
    // 전역 연산자 오버로딩 (클래스 내부 (1) oprator+와 동일의미)
    //Position operator+ (const Position a, int b)
    //{
    //	Position c;
    //	c.pos_x = a.pos_x + b;
    //	return c;
    //}
    
    
    //(2)
    //전역 연산자 오버로딩
    Position operator+ (int a, const Position & b)
    {
    	Position ret;
    
    	ret.pos_x = b.pos_x + a;
    	ret.pos_y = b.pos_y + a;
    
    	return ret;
    }
    
    
    int main()
    {
        int a =1;
        Position pos;
        Position pos2;
    
        pos = (pos + 1); // pos+1 :(1)연산 ,  pos = (pos+1) : (0)연산
        pos = (1 + pos); // 1+pos :(2)연산 ,  pos = (1+pos) : (0)연산
    
    
    }

     

     

     

    대입 연산자 오버로딩

    • 대입 연산자 오버로딩
      • [반환값] operator([인자])
        • 인자 : 오른쪽 피연산자
        • ex) (Myclass) a = (int) b
          • a: 클래스 자기 자신
          • b: 대입할 오른쪽 매개변수
    class Myclass
    {
    public:
        Myclass& operator=(int num)
        {
            _id = num; // 대입 연산 진행
            return *this; // 자기자신 return
        }
    
    public:
        int _id = 0;
    };
    
    
    
    int main()
    {
        Myclass m;
        m = 2; // 연산자 오버로딩
    
        return 0;
    }
    • 복사 대입 연산자 오버로딩
      • [반환값] operator([인자])
        • 자기 자신을 인자로 받는경우 예외처리 필요
        • 대부분 인자로 같은 클래스를 받는 경우가 대부분
      • 기본적으로 얕은 복사가 이루어짐 (컴파일러가 자동으로 생성해줌)
        • 포인터일경우 주소값도 동일하게 복사됨 (주소를 그대로 복사하기에 문제가 될 수 있음)
        • 데이터도 일반적으로 복사됨
      • 포인터가 있을 경우, 해당 부분의 깊은 복사를 진행해야함
        • 깊은 복사를 하지 않을경우, 대입때 사용된 other 클래스 객체 값 변경시 같이 변경됨
    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    using namespace std;
    
    
    class Myclass
    {
    public:
    
        Myclass(const char* str = "")
        {
            data = new char[strlen(str) + 1];
            strcpy(data, str);
        }
        
        // 일반적인 값 대입 연산
        Myclass& operator=(int num)
        {
            _id = num;
    
            return *this;
        }
        
        // 복사대입연산자 ( 깊은 복사 )
        Myclass& operator=(const Myclass& m)
        {
            // 자기자신 대입 방지
            if (this == &m)
                return *this;
    
            // 주소값 복사되는 얕은복사 방지 (깊은복사 진행)
            _id = m._id;
            data = new char[strlen(m.data) + 1];
            strcpy(data, m.data);
    
            //data = m.data;
            return *this;
        }
        
        // 복사대입 연산자 (얕은 복사)
        /*
         Myclass& operator=(const Myclass& m)
        {
            // 자기자신 대입 방지
            if (this == &m)
                return *this;
    
            _id = m._id;
            data = m.data; // 얕은복사 진행 (주소 + 데이터)
            
            return *this;
        }
        */
    
        void setData(const char* _data)
        {
            strcpy(data,_data);
        }
    
    public:
        int _id = 0;
        char* data;
    };
    
    
    
    int main()
    {
        Myclass m("Hello");
        Myclass m2("Bye");
    
        m2 = 2;
        m = m2;
        
        // 얕은 복사의 경우
        // m.data =="qqqq"
        // m2.data == "qqqq" 로 변경됨
        m2.setData("qqqq");
    
        //깊은 복사의 경우
        // m2.data == "qqqq" 변경
        // m.data 변경 없음
    
    
        
        
        return 0;
    }
    • 이동 대입 연산자
      • 인자로 받은 값을 연산하는 클래스로 값을 옮기고 초기화 해주는 역할
      • Other 데이터 -> 자기자신
        • 복사대입연산자와 다르게 주소를 그대로 사용해도 되므로 얕은복사 진행
        • 리소스 절약 가능
    Myclass
    {
    ...
      MyString& operator = (MyString&& other) noexcept
      {
             // 자기자신일 경우 패스
             if (this== &other) 
                  return*this;

             // 기존 자원 해제
             delete[] data;
         
              // data 옮기기
             data = other.data;
         
             // 다른 객체의 자원 포인터를 nullptr로 설정
              other.data = nullptr;
         
              return *this;
         }
    ...

    public:
        char *data;
    }

     

     

    전위 / 후위 연산자 오버로딩

    • 전위 연산자 오버로딩
      • ++a 형태
      • "++" 연산을 진행한 후 바로 적용
      • [반환값] operator++() 으로 생성
    class Position
    {
    public:
    	// 전위형 (++a)
    	Position& operator++()
    	{
    		pos_x++;
    		pos_y++;
    		return *this; // 연산 후 바로 적용
    	}
    
    public:
    	int pos_x = 0;
    	int pos_y = 0;
    };

     

    • 후위 연산자 오버로딩
      • a++ 형태
      • "++"연산은 이후에 적용되고, 원본값이 결과에 반환되어야함
      • [반환값] operator++(int) 으로 생성
    class Position
    {
    public:
    	// 후위형 (a++)
    	Position operator++(int)
    	{
            // 원본값 저장
    		Position ret = *this; 
    		
            // 1 증가
            pos_x++;
    		pos_y++;
            
    		// 원본값 return 
            return ret; 
    	}
    
    
    public:
    	int pos_x = 0;
    	int pos_y = 0;
    };

    '프로그래밍 언어 > C++' 카테고리의 다른 글

    동적할당  (0) 2024.07.03
    static  (0) 2024.07.03
    클래스 초기화  (0) 2024.07.03
    객체 지향 ( + 다형성 )  (0) 2024.07.02
    객체 지향 프로그래밍 (+ 상속성, 은닉성)  (0) 2024.07.02
Designed by Tistory.