#include <iostream>
#include <cassert>
using namespace std;
class MyString
{
public:
char* m_data = nullptr;
int m_length = 0;
public:
MyString(const char* source = "")
{
assert(source);
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';
}
char* getString()
{
return m_data;
}
int getLength()
{
return m_length;
}
~MyString()
{
delete[] m_data;
}
};
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;
}
//위 스코프를 빠져나가면서 hello가 할당받은 메로리를 해제해버린다.
cout << hello.getString() << endl;
}
006AF320
hello
006AF320
hello
硼硼硼硼硼硼硼硼^妊뺓
디버그모드로 추적해보면 copy는 스코프를 빠져나가면서 소멸자(~MyString())를 읽어드린다. 그때 m_data는 이미 지워지고 없는데 hello가 다시 m_data에 접근하니 이상한 값이 출력되는 것이다.
default copy constructor는 다음과 같이 생겼다.(컴파일러가 만들어서 넣어준다.)
//shallow copy
*this->m_data = source.m_data;
this->m_length = source.m_length;
비슷하지만 조금 다른 대입연산자를 오버로딩해보자.
#include <iostream>
#include <cassert>
using namespace std;
class MyString
{
public:
char* m_data = nullptr;
int m_length = 0;
public:
MyString(const char* source = "")
{
assert(source);
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';
}
//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;
}
}
//대입연산자 오버로딩
MyString& operator = (const MyString& source)
{
cout << "Assignment operator" << endl;
if (this == &source)//prevent self=assignment
{
return *this;
}
delete[] m_data;
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;
}
char* getString()
{
return m_data;
}
int getLength()
{
return m_length;
}
~MyString()
{
delete[] m_data;
}
};
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;
return 0;
}
'개발공부 > C++' 카테고리의 다른 글
형변환을 오버로딩하기 (0) | 2019.10.23 |
---|---|
키워드 : friend (0) | 2019.10.23 |
정적 멤버 (0) | 2019.10.23 |
다양한 반환 값들 (0) | 2019.10.22 |
다중포인터와 동적 다차원 배열 (0) | 2019.10.22 |