프로그래밍 언어/C++

C++ 연산자 오버로딩

ShovelingLife 2022. 7. 2. 10:24

좌측 값 그대로 변경된 상태에서 반환 시 불필요한 복사 방지하기 위해 무조건 & 레퍼런스로 반환할 것.

#include <iostream>
#include <algorithm>
#include <exception>
#include <string>

using namespace std;
class Test;

bool SAFETY_CHECK(Test& t) { if (&t == NULL) { cout << "Reference is NULL" << endl; return false; } else return true; }
bool SAFETY_CHECK(const Test& t) { if (&t == NULL) { cout << "Reference is NULL" << endl; return false; } else return true; }

class Test
{
    int val = 0;

public:
    Test() = default;

    Test(int _val) :val(_val) { }

    Test(const Test& _ref)
    {

        this->val = _ref.val;
    }

    Test operator+(Test& _ref)
    {
        cout << "+ 연산자 오버로딩" << endl;
        Test tmp = this->val + _ref.val;
        return tmp;
    }

    Test operator-(Test& _ref)
    {
        cout << "- 연산자 오버로딩" << endl;
        Test tmp = this->val - _ref.val;
        return tmp;
    }

    Test operator*(Test& _ref)
    {
        cout << "* 연산자 오버로딩" << endl;
        Test tmp = this->val * _ref.val;
        return tmp;
    }

    Test operator/(Test& _ref)
    {
        cout << "/ 연산자 오버로딩" << endl;
        Test tmp = this->val / _ref.val;
        return tmp;
    }

    Test& operator+=(Test& _ref)
    {
        cout << "+= 연산자 오버로딩" << endl;
        this->val += _ref.val;
        return *this;
    }

    Test& operator-=(Test& _ref)
    {
        cout << "-= 연산자 오버로딩" << endl;
        this->val -= _ref.val;
        return *this;
    }

    Test& operator*=(Test& _ref)
    {
        cout << "*= 연산자 오버로딩" << endl;
        this->val *= _ref.val;
        return *this;
    }

    Test& operator/=(Test& _ref)
    {
        cout << "/= 연산자 오버로딩" << endl;
        this->val /= _ref.val;
        return *this;
    }

    // 전위 연산자 ++
    Test& operator++()
    {
        cout << "전위 연산자 ++" << endl;
        ++val;
        return *this;
    }

    // 후위 연산자 ++
    Test & operator++(int _val)
    {
        cout << "후위 연산자 ++" << endl;
        Test tmp = *this;
        ++* this;
        return tmp;
    }

    // 전위 연산자 --
    Test& operator--()
    {
        cout << "전위 연산자 --" << endl;
        --val;
        return *this;
    }

    // 후위 연산자 --
    Test& operator--(int _val)
    {
        cout << "후위 연산자 --" << endl;
        Test tmp = *this;
        --* this;
        return tmp;
    }

    Test& operator=(Test& _ref)
    {
        cout << "= 연산자 오버로딩" << endl;

        if (*this != _ref)
            return *this;

    }

    Test& operator=(const Test& _ref)
    {
        cout << "= 연산자 오버로딩" << endl;

        if (*this != _ref)
            return *this;

    }

    bool operator!=(Test& _ref)
    {
        if (!SAFETY_CHECK(_ref))
            return false;

        cout << "!= 연산자 오버로딩" << endl;
        return this->val != _ref.val;
    }

    bool operator!=(const Test& _ref)
    {
        if (!SAFETY_CHECK(_ref))
            return false;

        cout << "const != 연산자 오버로딩" << endl;
        return this->val != _ref.val;
    }

    bool operator==(Test& _ref)
    {
        if (!SAFETY_CHECK(_ref))
            return false;

        cout << "== 연산자 오버로딩" << endl;
        return this->val == _ref.val;
    }

    bool operator==(const Test& _ref)
    {
        if (!SAFETY_CHECK(_ref))
            return false;

        cout << "const == 연산자 오버로딩" << endl;
        return this->val == _ref.val;
    }

    void Print(string type)
    {
        cout << type + " value : " << val << endl;
    }
};

int main()
{
    Test* p1 = new Test(5), * p2 = new Test(7), * p3 = new Test(6), * p4;
    Test t1, t2, t3;
    p3->Print("p3");
    p1->Print("p1");
    *p3 += *p1 += *p2;
    p3->Print("p3");
    p1->Print("p1");
    t1 = t2 = t3 = t1;
    (*p1)++; 
    ++(*p1);
    (*p2)--; 
    --(*p2);
    delete p1, p2, p3;
    return 0;
}