[C++] 복사생성자
REF : 윤성우의 열혈 C++
복사 생성자
- 생성자의 한 형태
- 객체를 복사한다.
int main(void)
{
SoSimple sim1(15, 20);
SoSimple sim2=sim1;
sim2.ShowSimpleData();
return ;
}
SoSimple sim2=sim1;
는SoSimple sim2(sim1);
과 같은 의미로 해석된다.- SoSimple형 객체를 생성하고
- 객체의 이름은 sim2로하고
- sim1을 인자로 받는 생성자를 호출해 객체 생성을 완료한다.
-
이때 호출되는게
복사생성자
이다. - 예시
SoSimple(const SoSimple ©) : num1(copy.num1), num2(copy.num2) { cout<<"Called SoSimple(SoSimple ©"<<endl; }
자동으로 삽입되는 디폴트 복사 생성자
- 복사생성자를 정의하지 않으면, 멤버 대 멤버의 복사를 진행하는
디폴트 복사 생성자
가 자동으로 삽입된다.
따라서
class SoSimple
{
private:
int num1;
int num2;
public:
SoSimple(int n1, int n2) : num1(n1), num2(n2)
{}
}
위 코드에는 자동으로 디폴트 복사 생성자
가 삽입된다.
class SoSimple
{
private:
int num1;
int num2;
public:
SoSimple(int n1, int n2) : num1(n1), num2(n2)
{}
SoSimple(const SoSimple& copy) : num1(copy.num1), num2(copy.num2)
{}
}
### 묵시적 변환을 막는 explicit
SoSimple sim2 = sim1;
SoSimple sim2(sim1);
- 위의 코드는 아래의 코드로 묵시적 변환이 일어나서 복사 생성자가 호출된다.
- 복사생성자의 묵시적 호출을 허용하지 않기 위해선
explicit SoSimple(const SoSimple ©) : num1(copy.num1), num2(copy.num2) { }
이렇게 선언해준다.
이렇게 명시적으로 복사생성자를 선언해준다면 앞으로 대입연산자
SoSimple sim2 = sim1;
처럼 객체의 생성과 초기화가 불가능해진다.
깊은 복사와 얕은 복사
디폴트 복사 생성자
는멤버 대 멤버의 복사
를 진행한다.- 그리고 이러한 방식의 복사는
얕은 복사
라고한다. - 이 경우에는, 멤버변수의 heap의 메모리 공간을 참조하면 문제를 일으킨다.
- 멤버의 메모리를 참조해 값을 복사해 할당하는 복사이다.
- 따라서 각 소멸자에서 두 번 메모리 할당을 해제하면 2번째에서 double free 오류를 보게된다.
깊은 복사를 위한 복사생성자의 정의
- 각각의 객체는 포인터로 참조하는 대상까지 깊게 복사한다.
- 클래스에 맞게 복사생성자에서 깊은 복사를 위한 코드를 작성하면 된다.
복사 생성자의 호출 시점
- 기존에 생성된 객체를 이용해 새로운 객체를 초기화
- Call-by-value 방식으로 함수 호출과정에서 객체를 인자로 전달.
- 객체를 반환하되, 참조형으로 반환하지 않는 경우.
이 복사생성자의 호출시점의 경우 공통적으로
객체를 새로 생성하되, 생성과 동시에 동일한 자료형의 객체로 초기화한다.
- 1번
SoSimple obj2 = obj1; //SoSimple obj2(obj1);
- 2번
void SoSimpleFunction(SoSimple ob) { } int main(void) { SoSimple obj(7); SoSimpleFunction(obj); //ob의 복사생성자가 호출되어 매개변수 ob에 obj의 값이 복사됨. }
- 3번
SoSimple SoSimpleFunction(SoSimple ob) { return (ob);//여기서 반환하면서 메모리 공간이 할당되며 ob로 초기화됨. } int main(void) { SoSimple obj(7); std::cout<<SoSimpleFunction(obj)<<std::endl;; // }
- 3번과같이 객체를 반환하게되면
임시 객체
가 생성되고, 복사생성자가 호출되면서 return 문에 명시된 객체가 인자로 전달된다. - 임시객체는
다음 행
으로 넘어가면 소멸된다. 참조자로 참조되는 임시객체는 바로 소멸되지 않는다.
댓글남기기