본문 바로가기
스터디/C++

[ C++ ] 복사 생성자( Copy Constructor )와 explicit

by 알 수 없는 사용자 2019. 9. 24.

복사 생성자 ( Copy Constructor )는 무엇일까?

 

일단 복사라는 말에 주목해보자.

우리가 변수의 값을 다른 변수에 복사를 하려면 다음과 같이 쓴다.

int num1 = 5;
int num2 = num1;
 

하지만 C++에서는 다음 방식과 동일하게 선언과 초기화를 지원한다.

int num1(5);
int num2(num1);

그럼 객체는 어떻게 될까?

A a;
A b = a;

A라는 클래스가 있고, a와 b 객체가 있다. 그럼 위와 같은 코드는 다음과도 동일하다.

A a;
A b(a);

즉, b객체를 새로 생성해서, a와 b가 멤버 대 멤버 복사가 일어난다.

근데 b의 생성자는 어떻게 호출이 될까?

 

일단 여기를 다시 해석해보자.

A b(a);

- A형 객체를 생성.

- 객체의 이름은 b.

- a를 인자로 받을 수 있는 생성자의 호출을 통해서 객체 생성을 완료한다.

 

그럼 b는 A형 객체를 인자로 받는 생성자가 있어야한다.

b (A &copy)
{
  . . .
}

 

다음 코드를 보자.

 

 

객체 a와 b는 멤버 대 멤버 복사가 생겼고, A형 객체를 인자로 받는 생성자가 호출된 것도 확인할 수 있다.

이러한 생성자를 가리켜서 복사 생성자 ( Copy Constructor )라고 한다.

 

또한 복사 생성자도 디폴트 복사 생성자( Default Copy Constructor )가 존재한다.

 

"멤버 대 멤버의 복사가 진행되는 디폴트 복사 생성자가 자동으로 삽입되니까, 굳이 복사 생성자를 정의할 필요는 없지 않나?"

 

 

이에 대한 얘기는 다음 포스팅인 깊은 복사와 얕은 복사에서 다시 다루겠다.

 

마지막 키워드인 explicit는 C++의 묵시적 변환을 막아주는 역할을 한다.

 

여기서 묵시적 변화란

A b = a;

C++ 이 위의 코드를

A b(a);

으로 바뀌는 것을 말한다.

 

이는 결국, 복사 생성자가 묵시적으로 호출된 것으로 볼 수 있다. 따라서 위와 같은 유형의 변환이 마음에 들지 않는다면, 복사 생성자의 묵시적 호출을 허용하지 않으면 된다. 허용하지 않는 방법은 복사 생성자 앞에 explicit을 붙이면 된다.

 

그럼 위와 같은 형태는 허용하지 않고

 

위와 같은 형태는 허용이 된다.

 

explicit은 말 그대로 명백하다는 의미로, 코드의 명확성을 높이기 위해 존재한다.

묵시적 변환이 많이 발생하는 코드일수록 코드의 결과를 예측하기 어려워지기에 explicit을 사용하기도 한다.