Channi Studies

[C++] 대입 연산자 오버로딩 (복사) | Assignment Operator Overloading (copy) 본문

C++/기타

[C++] 대입 연산자 오버로딩 (복사) | Assignment Operator Overloading (copy)

Chan Lee 2024. 1. 9. 00:18

C++에서는, 한 객체에서 다른 객체로의 대입 연산자 사용이 가능합니다.

Mystring s1 {"Frank"};
Mystring s2 = s1;	// NOT Assingment
			// Same as Mystring s2 {s1};

s2 = s1	// Assignment

 

C++ 컴파일러는 기본 대입 연산자를 생성합니다.

이는 얕은 복사(shallow copy / memberwise assignment) 입니다.

 

만약 우리가 사용하는 클래스의 속성 중 raw pointer를 사용한다면,

우리는 깊은 복사(deep copy)를 해야합니다.

 

 

이번 포스트에서는 c-style string값의 포인터를 속성으로 지니는 Mystring 클래스를 다뤄보겠습니다.

class Mystring {
private:
  char *str; // C-style string

public:
  Mystring();
  Mystring(const char *s);
  Mystring(const Mystring &source);
  ~Mystring();

  void display() const;
  int get_length() const;
  const char *get_str() const;
};

 

생성자 2개, 복사 생성자, 소멸자, 디스플레이 메소드, 길이를 반환하는 메소드, 그리고 문자열 반환 메소드가 있습니다.

 

클래스 멤버들에 대한 정의는 다음과 같습니다

Mystring::Mystring() : str{nullptr} {
  str = new char[1];
  *str = '\0';
}

Mystring::Mystring(const char *s) : str{nullptr} {
  if (s == nullptr) {
    str = new char[1];
    *str = '\0';
  } else {
    str = new char[std::strlen(s) + 1];
    std::strcpy(str, s);
  }
}

Mystring::Mystring(const Mystring &source) : str{nullptr} {
  str = new char[strlen(source.str) + 1];
  std::strcpy(str, source.str);
}

Mystring::~Mystring() { delete[] str; }

void Mystring::display() const {
  std::cout << str << " : " << get_length() << std::endl;
}

int Mystring::get_length() const { return std::strlen(str); }
const char *Mystring::get_str() const { return str; }

 

위 클래스에 대해서, 

(deep) copy assignment operator를 오버로딩해보겠습니다. 

 

 

기본적인 syntax는 다음과 같습니다.

Type &Type::Operator=(const Type &rhs);

 

즉, 다음과 같이 할 수 있습니다.

Mystring &Mystring::operator=(const Mystring &rhs);

 

이렇게 오버로딩을 한 상태에서

s2 = s1;	// 는

s2.operator=(s1);	// 를 호출합니다

 

그리고 이 연산자의 세부 정의는 다음과 같습니다.

Mystring &Mystring::operator=(const Mystring &rhs) {
  if (this == &rhs)	// p1 = p1;
    return *this;	// return current object

  delete[] this->str;
  str = new char[std::strlen(rhs.str) + 1];
  std::strcpy(str, rhs.str);

  return *this;
}

 

만약 스스로가 우변과 동일하다면 (스스로에게 스스로를 저장하려고 하면)

현재 객체를 반환합니다.

 

그렇지 않다면, 스스로의 문자열의 데이터의 할당을 취소하고, 

새로운 문자열을 동적으로 할당한 뒤,

해당 문자열에 우변의 객체의 문자열을 복사하여 저장하고 이를 반환합니다.

 

 

위 경우에서는 한가지의 속성이 존재하기 때문에 하나의 속성에 대해서만 deep copy를 했지만,

만약 여러개의 속성이 존재한다면 모든 속성에 대해서 이를 행해야 합니다.