일상 코딩
[C++/9.11] 대입"=" 연산자 오버로딩, 깊은 복사, 얕은 복사 문제점 및 해결 방법 본문
C++/따배C++ 09강 연산자 오버로딩
[C++/9.11] 대입"=" 연산자 오버로딩, 깊은 복사, 얕은 복사 문제점 및 해결 방법
polarcompass 2021. 10. 31. 14:26728x90
#include <iostream>
#include <cassert>
using namespace std;
class MyString
{
//private:
public:
char *m_data = nullptr;
int m_length = 0;
public:
// 문자열 받고 있는 생성자
MyString(const char *source = "")
{
assert(source);
// 문자열 길이 함수
// +1 을 한 이유는 문자열 끝에 문자열 끝을 나타내기 위한 '\0'을 넣기 위함.
m_length = std::strlen(source) + 1;
// 동적할당 메모리
m_data = new char[m_length];
// 깊은 복사
for (int i = 0; i < m_length; ++i)
m_data[i] = source[i];
m_data[m_length - 1] = '\0';
}
// delete
// 만약에 복사 생성자가 구현이 안되어있을 경우
// 얕은 복사를 막는 차선책
// 가장 좋은것은 복사 생성자를 만드는 것이 가장 좋다.
// MyString(const MyString &source) = delete;
// copy constructor
MyString(const MyString &source)
{
cout << "Copy constructor " << endl;
m_length = source.m_length;
if (source.m_data != nullptr)
{
m_data = new char[m_length];
for (int i = 0; i < m_length; ++i)
m_data[i] = source.m_data[i];
}
else
m_data = nullptr;
}
// 대입 연산자
// Assignment Operator
MyString &operator=(const MyString &source)
{
// default copy constructor 코드
// 동적 할당 메모리로 되어있을 경우엔 이렇게하면 문제가 생김.
// this->m_data = source.m_data;
// this->m_length = source.m_length;
cout << "Assignment operator " << endl;
// hello = hello 와 같은 코드를 방지하기 위한 방어 코드
// this의 주소와 &source의 주소를 비교하여 같으면 그냥 넘김.
if (this == &source) //prevent self-assignment
return *this;
// 그전에 생성된 메모리가 있을 경우 제거해준다.
delete[] m_data;
// 깊은 복사 코드
m_length = source.m_length;
if (source.m_data != nullptr)
{
m_data = new char[m_length];
for (int i = 0; i < m_length; ++i)
m_data[i] = source.m_data[i];
}
else
m_data = nullptr;
return *this;
}
// 소멸자
~MyString()
{
delete[] m_data;
cout << "delete MyString" << endl;
}
char *getString() { return m_data; }
int getLength() { return m_length; }
};
int main()
{
MyString hello{"Hello"};
cout << (int *)hello.m_data << endl;
cout << hello.getString() << endl;
{
MyString copy = hello;
cout << (int *)copy.m_data << endl;
cout << copy.getString() << endl;
}
cout << hello.getString() << endl;
// 구분선
for (int i = 0; i < 20; i++)
cout << "-";
cout << endl;
// copy constructor 호출됨
MyString str1 = hello;
// 코딩시 MyString str1(hello);로 작성시 동일하고 덜 헷갈리게 된다.
MyString str2;
// assignment operator 호출됨.
str2 = hello;
return 0;
}
728x90
'C++ > 따배C++ 09강 연산자 오버로딩' 카테고리의 다른 글
[C++/9.12] initialize_list 생성자 (0) | 2021.10.31 |
---|---|
[C++/9.10] 변환 생성자, explicit, delete (0) | 2021.10.31 |
[C++/9.09] 복사 생성자, 복사 초기화 반환값 최적화 (0) | 2021.10.31 |
[C++/9.08] 형변환 오버로딩 typecast overloading (0) | 2021.10.30 |
[C++/9.07] 괄호"()" 연산자 오버로딩과 함수 객체 Functor (0) | 2021.10.30 |