C++/Overloading 2021. 3. 19. 19:32

대입 연산자 오버로딩 (Assignment Operator Overloading)

  • 자기 자신을 assignment할 때(hello = hello 등) 발생할 수 있는 문제를 미리 방지할 수 있다.

  • 깊은 복사를 직접 구현할 수 있다.

    #include <iostream>
    #include <cassert>
    
    class MyString
    {
        char* data_ = nullptr;
        int        len_ = 0;
    
    public:
        MyString(const char* source = "")
        {
            assert(source);
    
            len_ = std::strlen(source) + 1;
            data_ = new char[len_];
    
            for (int i = 0; i < len_; ++i)
                data_[i] = source[i];
            data_[len_ - 1] = '\0';
        }
    
        ~MyString()
        {
            delete[] data_;
        }
    
        MyString(const MyString& source)
        {
            std::cout << "Copy constructor\n";
    
            len_ = source.len_;
    
            if (source.data_ != nullptr)
            {
                data_ = new char[len_];
    
                for (int i = 0; i < len_; ++i)
                    data_[i] = source.data_[i];
            }
            else
                data_ = nullptr;
        }
    
        char*& getString() { return data_; }
    
        MyString& operator = (const MyString& source)
        {
            std::cout << "Assignment operator\n";
    
            if (this == &source)  // prevent self-assignment
                return *this;
    
            delete[] data_;
    
            len_ = source.len_;
    
            if (source.data_ != nullptr)
            {
                data_ = new char[len_];
    
                for (int i = 0; i < len_; ++i)
                    data_[i] = source.data_[i];
            }
            else
                data_ = nullptr;
        }
    };
    
    int        main()
    {
        using namespace std;
    
        MyString    hello("Hello");
    
        cout << (int*)hello.getString() << endl;
        cout << hello.getString() << endl;
    
        {
            MyString    copy;
    
            copy = hello;
    
            cout << (int*)copy.getString() << endl;
            cout << copy.getString() << endl;
        }
    
        cout << hello.getString() << endl;
    }
    
    /* stdout
    00C0EAD8
    Hello
    Assignment operator
    00C0E5D0
    Hello
    Hello
    */
  • 같은 자료형을 인자로 넣는 초기화는 Copy Constructor를 호출한다.

    • 대입 연산자를 통해 값을 넣으려면 초기화가 아닌 대입을 해야한다.

      #include <iostream>
      #include <cassert>
      
      class MyString
      {
          char* data_ = nullptr;
          int        len_ = 0;
      
      public:
          MyString(const char* source = "")
          {
              assert(source);
      
              len_ = std::strlen(source) + 1;
              data_ = new char[len_];
      
              for (int i = 0; i < len_; ++i)
                  data_[i] = source[i];
              data_[len_ - 1] = '\0';
          }
      
          ~MyString()
          {
              delete[] data_;
          }
      
          MyString(const MyString& source)
          {
              std::cout << "Copy constructor\n";
      
              len_ = source.len_;
      
              if (source.data_ != nullptr)
              {
                  data_ = new char[len_];
      
                  for (int i = 0; i < len_; ++i)
                      data_[i] = source.data_[i];
              }
              else
                  data_ = nullptr;
          }
      
          char*& getString() { return data_; }
      
          MyString& operator = (const MyString& source)
          {
              std::cout << "Assignment operator\n";
      
              if (this == &source)  // prevent self-assignment
                  return *this;
      
              delete[] data_;
      
              len_ = source.len_;
      
              if (source.data_ != nullptr)
              {
                  data_ = new char[len_];
      
                  for (int i = 0; i < len_; ++i)
                      data_[i] = source.data_[i];
              }
              else
                  data_ = nullptr;
          }
      };
      
      int        main()
      {
          using namespace std;
      
          MyString    hello("Hello");
      
          MyString    str1 = hello;
      
          MyString    str2(hello);
      
          MyString    str3{ hello };
      
          MyString    str4;
      
          str4 = hello;
      }
      
      /* stdout
      Copy constructor
      Copy constructor
      Copy constructor
      Assignment operator
      */