#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 |