본문 바로가기

개발/C&C++

(C/C++ 속성 정리) 28일 차 : 복사 생성자의 이해

안녕하세요 넬다이입니다.

오늘은 복사 생성자에 대해서 알아보는 시간을 가져보도록 하겠습니다.


복사생성자

복사 생성자를 알기 위해서는 클래스가 생성될 때 기본적으로 생성되는 것들이 있습니다.

그것은 1. 기본 생성자 , 2. 소멸자 , 3. 기본 대입 연산자 , 4. 기본 복사 생성자 이렇게 있습니다. 이것은 꼭 암기해주시기를 부탁드립니다. 

여기서 기본적으로 기본 복사 생성자가 생성이 되는데요 기본 복사 생성자는 전일 차에서 말하는 얕은 복사를 진행하는 생성자를 만들어 주게 됩니다. 쉽게 코드로 보시지요

class CObj
{
private:
	int		m_iValue;
	int		m_iValue2;
public:
	//이것은 우리가 생성하는게 아닌 생성자가 없다면은 컴파일러가 자동으로 생성해주는 함수입니다.
	/*CObj(const CObj& rObj)
	{
		m_iValue = rObj.m_iValue;
		m_iValue2 = rObj.m_iValue2;
	}*/

}

위에 코드를 보시게 되면은 기본 대입 연사자이다 보니깐 넘어오는 값들을 바로 대입으로 값을 복사하는 것을 볼 수 있습니다. 이렇게 되면은 저 값이 포인터일 때는 분명 문제가 될 것입니다. 

 

포인터가 가리키는 주소까지 단순 복사가 일어나기 때문에 공간 자체가 재할당 된 것이 아니므로 2개의 객체가 같은 공간을 가리키고 있는 것이다.

그렇기 때문에 포인터를 delete를 했을 때 문제가 생기는 것입니다.

 

기본 복사 생성자는 클래스 내부에 선언한 멤버 변수의 개수와 타입에 영향을 받고 멤버 변수 대 멤버 변수 1:1 복사만이 일어나기 때문에 이러한 문제가 발생하는 것입니다.

 

복사 생성자가 호출되는 형태가 3가지가 기본적으로 있는데 아래와 같습니다.
1. 기존에 생성된 객체로 새로운 객체를 초기화할 때

// 아래와 같이 할때 obj안에다가 obj2의 값을 넣어주기 위해서 복사생성자를 진행합니다.
CObj obj = obj2;

2. 함수 호출할 때 객체를 값에 의해 전달하는 경우

//아래와 같이 Test라는 함수를 호출할때 TestObject를 넣어주고
//변수로 받을때 obj에 TestObject의 값을 넣으므로 복사생성자가 호출됩니다

void Test(CObj obj)
{

}

void main()
{
	CObj TestObject
	Test(TestObject);
}

3. 함수 내에서 객체를 값에 의해 리턴하는 경우

//아래와 같이 함수에서 return 값에 obj를 넣어서 받는 곳에서 리턴값으로 값 복사가 일어난다.
    
CObj Function(void)
{
    CObj obj;
    return obj;
}

 

이렇듯 복사 생성자를 통해서 문제가 생길 수 있는 현상이 있습니다. 이를 보안하기 위해서는 우리는 복사 생성자를 직접 만들어서 깊은 복사를 할 수 있도록 유도하는 코드를 작성해야 하는 것입니다..

 

[개발/C&C++] - (C/C++ 속성 정리) 27일 차 : 깊은 복사와 얕은 복사의 이해

[개발/C&C++] - (C/C++ 속성 정리) 26일 차 : Static이란? 및 특징

[개발/C&C++] - (C/C++ 속성 정리) 25일 차 : Const 한정자란?

[개발/C&C++] - (C/C++ 속성 정리) 24일 차 : 객체지향 프로그래밍이란?

[개발/C&C++] - (C/C++ 속성 정리) 23일 차 : 분활컴파일 및

[개발/C&C++] - (C/C++ 속성 정리) 22일 차 : 함수포인터를 이용한 사칙연산 계산기 만들기