본문 바로가기
개발/C++

복사 생성자와 복사 대입연산자

by 사과잼빵 2016. 10. 22.
#pragma once
#include <iostream>

using namespace std;

class CPerson
{
public:
	CPerson(const char* name, const int age);
	CPerson(void);
	~CPerson(void);

	//복사 생성자
	CPerson(const CPerson& copyPerson);
	
	//복사 대입연산자
	CPerson& operator=(const CPerson& copyPerson);

public:
	int iAge;
	char* strName;
private:
	enum DEFULATVALUES
	{
		eMaxNameSize = 100
	};
		
};



Person 클래스의 복사 생성자, 복사 대입연산자의 선언 부분이다. 선언 해주지 않으면 컴파일러가 디폴트 복사 생성자와 디폴트 복사 대입 연산자를 생성해준다.




#include "Person.h"

CPerson::CPerson(void)
	:strName(nullptr), iAge(0)
{
	cout<<"기본 생성자 호출"<<endl;
}


CPerson::CPerson(const char* name, const int age)
{
	cout<<"생성자 호출"<<endl;
	strName = new char[eMaxNameSize];	
	strcpy(strName, name);
}

CPerson::CPerson(const CPerson& copyPerson)
{
	cout<<"복사 생성자 호출"<<endl;
	strName = new char[eMaxNameSize];
	iAge = copyPerson.iAge;
	strcpy(strName, copyPerson.strName);

}

CPerson& CPerson::operator=(const CPerson& rightHand)
{
	cout<<"복사 대입 연산자 호출"<<endl;
	if(nullptr == strName)
	{
		strName = new char[eMaxNameSize];
	}
	iAge = rightHand.iAge;
	strcpy(strName, rightHand.strName);
	return *this;
}


CPerson::~CPerson(void)
{
}

CPerson 클래스의  복사 생성자 및 복사 대입연산자를 정의해주는 부분입니다.
디폴트 복사 생성자의 경우 단순한 값만 복사하도록 생성되기 때문에 멤버 변수로 포인터를 가질 경우 얕은 복사의 문제로 인해 복사 생성 시 서로 다른 객체의 멤버가 같은 곳을 가리키는 문제가 발생합니다.
따라서 위의 strName과 같은 멤버 변수는 직접 포인터가 가리키는 내용들을 쫙 복사해주게 정의해줘야합니다.

- 복사 생성자와 복사 대입연산자는 어떻게 다른가? 

이 두 함수가 어떻게 다른지 확인해보기 위해 다음과 같은 코드를 작성했습니다.


#include <stdio.h>
#include "Person.h"

int main(void)
{
	int inputValue;
	CPerson p1("철수", 5);
	
	//복사 생성자 테스트
	cout<<endl<<"-------복사 생성 시작 --------"<<endl;
	CPerson p2(p1);
	cout<<endl<<"-------복사 생성 끝 --------"<<endl;

	//복사 대입 연산자 테스트
	cout<<endl<<"-------복사 대입 시작 --------"<<endl;
	CPerson p3;
	p3 = p1;
	cout<<endl<<"-------복사 대입 끝 --------"<<endl;

	std::cin>>inputValue;
	return 0;
}

결과는 다음과 같습니다.



복사 생성의 경우 기본 생성자를 따로 호출하지 않고 복사 생성자만 호출됩니다.

하지만 복사 대입의 경우 기본 생성자로 객체를 생성후 복사 대입 연산을 해야한다는 것을 알 수 있습니다.

'개발 > C++' 카테고리의 다른 글

explicit 키워드  (0) 2016.10.20
가상 함수  (0) 2015.10.06
c++11에 추가된 기능 - auto 변수  (0) 2015.09.30
클래스 전방선언  (0) 2015.09.30