본문 바로가기
C++ 공부

operator 01

by Dev_Hugh 2021. 8. 20.
728x90
반응형

Study about operator overloading

  • operator overloading은 함수!!
  • 연산자 재정의는 class만 가능
  • 사용자 코드에서 보편적 직관에 따라 제작자 코드를 사용가능하게 작성하자
  • 즉 자료에 대해 사용자가 공부를 하지 않아도 잘 사용할수있게 작성하자는 것

보편적 직관 예시

// 제작자 코드
class MyData { };
// 사용자 코드
int main(void)
{
    MyData a;
    a += 3; // 1번
    // 3을 담는 변수 주소와 그 사이즈를 넘김
    a.Append(&3, int); // 2번
}
  • 사용자는 MyData a 라고 선언해도 "제작자가 내부를 알아서 초기화 해줬겠지" 라고 생각할수있으니 주의
  • main에서 사용자는 1번과 2번중 1번이 더 직관적임을 느낌

arithmetic operators

산술 연산자 예시

class MyData
{
public:
    MyData() 
    { 
        cout << "MyData()" << endl;
    }
    ~MyData() 
    { 
        cout << "~MyData()" << endl
    }
    int GetData() const
    {
        return m_Data;
    }
    void SetData(int a)
    {
        m_Data = a;
    }
    MyData(int my) : m_Data(my)
    {
        cout << "MyData(int)" << endl;
    }
    MyData(const MyData &my)
    {
        cout << "MyData(const &)" << endl;
    }
    MyData(const MyData && my)
    {
        cout << "MyData(const MyData &&)" << endl;
    }
    // 허용되는 변환 (5번 실행시 주석)
    operator int(void)
    {
        return m_Data;
    }

    // 동형클래스끼리 덧셈시 향상 ver
    MyData operator+ (const MyData &my)
    {
        return MyData()
        // return MyData(this->m_Data + my.m_Data);
    }

    // 대입연산자
    void operator= (int a)
    {
        // m_Data = a;
        SetData(a);
    }

    // 불필요한 복사 막는 효율버전
    MyData& operator= (const MyData &my)
    {
        SetData(my.GetData());
        return *this;
    }
private:
    int m_Data = 0;
};

int main(void)
{
    MyData a;
    MyData b;
    a + b;

    a.SetData(5); // 1번
    a = 5; // 2번
    a.operator= (5); // 3번
    a = b = 5; // 4번

    MyData c;
    MyData &result = a + b;
    c = a + b; // 5번
    c = result; // 6번

    cout << "End of main()" << endl;
    return 0;
}
  • 기본 타입(int double float char 등)이 아닌 타입에 대해 연산자를 수행시 연산자 재정의가 필요하다.
  • 사용자 측면에서 1번대신 2번을 쓸수있게 대입연산자를 정의해주면 어떨까?
  • 대입연산자에서 이미 값을 받는 SetData함수가 있으니 이를 불러는게 더 좋다
  • 이때 함수가 함수를 부르는 overhead에 대해 컴파일러 최적화를 공부하면 걱정안해도 된다

3번 출력 설명

  • 3번도 호출되는걸 봐선 연산자 정의도 함수임을 다시 강조

4번 출력 설명

  • 4번을 호출하면 현재 대입연산자는 반환이 void라 에러
  • 이를 해결하고자 반환을 int로 바꾸고 4번에서 중단점을 걸고 디버그시 대입연산을 두번부르는걸 확인가능
  • MyData를 반환해주면 되는데 이때 그냥 MyData를 받아서 반환시 불필요한 복사가 2번일어남 (왜 2번인지 생각)

5번 출력 설명

  • 5번 실행시 임시객체 포함 5개의 객체가 불린다
  • 매개변수에 const를 붙이면 1개의 불필요한 객체가 줄어든다 총 4개
  • return 부분을 주석된것처럼 바꾸면 생성자가 default에서 (int)가 들어간걸로 바뀐다
  • 이제 소멸시점을 찍기위해 return 부분의 주석을 바꾸고 실행하면 (int)소멸자만 "end of main" 전의 호출됨

6번 출력 설명

  • 이 경우는 소멸자가 스코프가 다 끝나야 호출

결론

  • 정말 많은 출력형태를 찍어봤는데 항상 눈에 보이지않는 임시객체와 생성자 소멸자의 호출시점을 잘 생각하면서 작성하자
728x90
반응형

'C++ 공부' 카테고리의 다른 글

inheritance 01  (0) 2021.08.20
operator 02  (0) 2021.08.20
constructor 05  (0) 2021.08.20
constructor 04  (0) 2021.08.20
constructor 03  (0) 2021.08.20