728x90
반응형

연산자 오버로딩(Overloading)

 -> 함수의 오버로딩 규칙을 연산자에 적용하는 문법이다.

 

string을 사용하지 않고 연산자 오버로딩을 사용해보는 과제였다.

 

	CMyString str1("Hello");
	CMyString str2 = "World";
	CMyString str3;
	CMyString str4;
	CMyString str5;

여기서

CMyString str1("Hello");             // 생성자 호출

CMyString str2 = "World";          // 객체 생성 시 대입 연산자는 복사 생성자의 호출

<<< 복사 생성자의 주의할점 >>>

얕은 복사의 문제가 생길 수 있다 -> 깊은 복사방식으로 구현하자!

(깊은 복사 - 서로 다른 주소 값을 가지게 만들어 준다.)

class CMyString
{
public:
	CMyString() :m_pBuff("") {}		// 생성자
	CMyString(char* _pBuff)
	{
		m_pBuff = new char[strlen(_pBuff) + 1];
		strcpy_s(m_pBuff, strlen(_pBuff) + 1, _pBuff);

	}
	CMyString(CMyString& _rBuff)
	{
		m_pBuff = new char[strlen(_rBuff.m_pBuff) + 1];
		strcpy_s(m_pBuff, strlen(_rBuff.m_pBuff) + 1, _rBuff.m_pBuff);

	}		// 깊은 복사 - 다른 주소를 가지기 위해
~CMyString()
	{
		if (!m_pBuff)			
		{
			delete[] m_pBuff;
			m_pBuff = nullptr;
		}

	}

여기 소멸자에 동적할당 해제를 해줬는데 처음에 if(m_pBuff)로 했더니

_CrtisValidHeapPoiner(block) <- 이런 오류가 생겼다.

이 오류는 잘못된 포인터를 참조할 때 발생한다고 한다. 느낌표를 붙이니까 되긴 되는데.. 왜 이렇게 해야 되는거지.....?

 

IsValidHeapPointer라는 어썰트는 말 그대로 해당 포인터가 valid(유효)한지 체크하는 겁니다.

여기서 말 하는 힙(Heap)은 현재 실행 중인 프로그램의 로컬 힙 메모리를 가리키는 것으로, 즉, 해당 포인터가 참조하는 메모리 주소가 프로그램 상에서 new 등으로 할당한 공간의 주소인지를 체크하는 것입니다.

(https://hashcode.co.kr/questions/2996/c-%EB%A9%94%EB%AA%A8%EB%A6%AC%ED%95%B4%EC%A0%9C-debug-assertion 참고)

 

2번째 시도

heap corruption detected 오류 발생

동적할당 해제 부분에서 할당 된 메모리보다 더 큰 메모리를 해제하려고 해서 발생한 오류이다.

하지만, 메모리의 크기에는 문제가 없었고 디버깅을 해보니 str1과 str2만 동적할당 해제가 되지않고 있었다. str1과 str2만 +=연산자를 사용했다. 다시 보니 +=연산자에서 얕은복사로 인하여 발생한 오류였다.

+= 연산자에 깊은 복사로 new로 해주니 오류없이 잘 돌아갔다. 해결해서 다행!!!ㅜㅜ

#define SAFE_DELETE_Arr(p)	if(p){ delete[] p; p = nullptr;}
CMyString::~CMyString()
{
	Release();
}

void CMyString::Release()
{
	SAFE_DELETE_Arr(m_pBuff)				// 동적할당 해제
}

이렇게 해도 안됨,,

 

이제 연산자 오버로딩을 하기 전

ostream& operator<<(ostream& _out, CMyString& _string)
{

	_out << _string.Get_Buff();

	return _out;
}

콘솔창 출력을 위한 코드이다. 전역에 있는 함수였는데 CMyString에 있는 객체를 받아와서 출력해야하기 때문에 클래스 내부에 Get_Buff()함수를 이용해 접근하였다.

char*	Get_Buff()
	{
		return m_pBuff;
	}

난 생성자에 m_pBuff를 ""로 초기화를 하고 여기 Get함수에서 m_pBuff를 return했는데

이렇게 말고 

char* CMyString::Get_Buff()
{
	if(m_pBuff)					
		return m_pBuff;						
	return "";
}

 

생성자에는 nullptr로 초기화를 하고 Get함수 내부에는 이런식으로 하는 것이 더 좋을듯 하다.

	cout << str1 << endl;
	cout << str2 << endl;
	cout << str3 << endl;
	cout << str4 << endl;
	cout << "==================================================" << endl;

이제 출력을 해보면

이렇게 나온다.

728x90
반응형

'c++ > c++' 카테고리의 다른 글

알고리즘 - for_each  (0) 2021.05.29
STL - vector container  (0) 2021.05.26
STL(Standard Template Library)  (0) 2021.05.23
연산자 오버로딩 - string class 구현2  (0) 2021.05.23
const와 포인터  (0) 2021.05.22

+ Recent posts