대입 연산자 오버로딩
대입 연산자(=)는 객체에 다른 객체의 값을 할당하는 데 사용됨
대입 연산자 오버로딩을 통해 자신이 정의한 클래스에 대해 대입 연산자의 동작을 사용자 지정하거나 확장함
기본적으로 C++ 컴파일러는 멤버변수 단위로 얕은 복사(shallow copy)를 수행하지만, 깊은 복사(deep copy)를 수행하도록 지정할 수 있음
/* 생략 */
// 대입 연산자 오버로딩
String &operator=(const String &rhs) { // 참조로 선언하지 않으면 rhs(s1)이라는 복사 생성자가 작동해서 복잡해짐.
if (this != &rhs) { // 자기 자신을 대입하는 경우를 막기.
// 만약 strData에 어떤 값이 존재한다면, delete해줘야 함.
delete[] strData; // strData가 NULL이면 어차피 작동 X
strData = new char[rhs.len + 1];
cout << "strData할당: " << (void *)strData << endl;
strcpy(strData, rhs.strData); // 깊은 복사
len = rhs.len;
} // 깊은 복사
return *this; // this : 함수가 속한 객체의 주솟값. *this --> 객체
}
/* 생략 */
int main() {
String s1("안녕");
String s2(s1); // 복사 생성자
// 기본적으로 소멸은 선언의 역순
String s3;
/*
int a = 5;
int b;
int c = b = a; --> b에 a의 값을 대입하고 5를 return해서 c = 5가 된다.
*/
s3 = s1;
// s3.operator=(s1)
// 즉, s3 객체의 멤버함수가 s1을 매개변수로 전달받아서 작동한다(+ 자신을 반환)
// 연산자 오버로딩 사용하여 얕은 복사 방지
String s4("Hello");
s4 = s4; // hello 문자열을 해제하면 len만 남아서 strdata 할당이 되서 쓰레기값만 들어있는데, 쓰레기값이 strcpy를 만나 쓰레기값이 저장됨.
cout << s1.GetStrData() << '\n';
cout << s2.GetStrData() << '\n';
cout << s3.GetStrData() << '\n';
cout << s4.GetStrData() << '\n'; // 예외처리 안하면 쓰레기값 출력
}
등호 연산도 리턴값을 가진다
int a = 5, b;
int c = b = a; --> b에 a의 값을 대입하고 5를 return해서 c = 5가 된다.
String &operator=(const String &rhs)
s3 = s1; 에서 발생할 수 있는 얕은 복사를 연산자 오버로딩 사용하여 방지
등호 연산은 리턴값을 갖기 때문에, 반환 타입 String &
매개변수를 참조로 선언하지 않으면 rhs(s1)이라는 복사 생성자가 작동해서 복잡해짐.
만약 String &operator=(const String rhs)로 선언했다면, rhs에 s1이 이전에 만들어둔 복사 생성자를 통해 복사되는 과정을 거치게 됨(비효율적임)
레퍼런스로 만들어줌으로써 복사하는 과정을 스킵할 수 있다.
이 내용은 PS에서도 중요하므로 꼭 기억해야 한다.
반환 타입이 참조형인 이유 --> 값을 리턴하는 과정에서 임시 변수에 객체 복사가 또 일어나므로, 참조형으로 선언
if (this != &rhs)
- 자기 자신(같은 주소를 갖는 객체)을 대입하는 경우 자신이 갖고 있는 값이 delete[] strData;로 인해 문자열 값이 존재하지 않고 쓰레기 값만 존재하게 됨
delete[] strData;
- 예를 들어 String s3("Hello");로 초기화된 상태인데, s3 = s1을 하려면, 기존에 있는 strData를 해제해줘야 함
참조) 두들낙서 C/CPP 강의
'Programming Language > C++' 카테고리의 다른 글
[C++] Implicit Conversion(묵시적 형변환) (0) | 2024.06.27 |
---|---|
[C++] 이동 시맨틱(Move Semantics): 이동 생성자, 이동 대입 연산자 (0) | 2024.06.27 |
[C++] 복사 생성자 오버로딩 (0) | 2024.03.12 |
[C++] 깊은 복사와 얕은 복사(Deep Copy, Shallow Copy) (0) | 2024.03.12 |
[C++] 동적할당 (0) | 2024.02.04 |