Minwoo Dev.

[C++] 복사 생성자 (Copy Constructor) 본문

C++

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

itisminu 2024. 6. 27. 13:50
728x90
반응형
SMALL

복사 생성자는 "="을 사용화여 연산을 수행하는 경우에 자동적으로 실행된다.

Person p1("minwoo",23);
Person p2 = p1;

위와 같은 경우에, p2에 p1의 값을 그대로 "복사하여" 저장하게 된다.

따라서 컴파일러는 위 코드를 아래처럼 변환하여 수행하게 된다.

 

Person p1("minwoo",23);
Person p2(p1);

 

기본 생성자의 모양과 굉장히 비슷하게 생기지 않았는가 ?

다른 점이라면 객체에 들어가는 각 값이 아닌 또다른 하나의 객체가 통째로 들어간다는 점이다.

우리는 위와 같은 모습의 생성자를 복사 생성자(Copy Constructor)라고 한다.

 

복사 생성자(Copy Constructor)

class Person{
private:
	char * name;
    int age;
public:
	Person(char* name=nullptr, int age=0):this->name(name),this->age(age){} // 생성자
    Person(Person &copy):this->name(copy.name),this->age(copy.age){} // 복사 생성자
    ...
}

 

위처럼 생성자와 인자로 전달되는 부분이 다르다.

복사 생성자는 인자로 해당 객체의 참조값이 전달된다.

 

 

 

복사 생성자가 실행되는 상황에는 크게 세 가지가 존재한다.

 

1. 새로운 객체에 존재하던 객체를 대입할 때

Person p1("minwoo",23);
Person copy = p1; // 복사 생성자 실행!

 

p1이라는 기존에 존재하던 객체를 copy에 대입하면, p1의 주소값과 copy의 주소값이 같아지는 것이 아니다.

p1에 있는 값을 임시 객체에 복사한 후에 그 객체를 copy에 다시 복사하는 것이다.

따라서 복사 생성자가 실행되게 된다.

 

2. Call-by-value 형식의 인자를 전달할 때

void ShowPersonInfo(Person p){
    cout<<"name : "<<p.name<<endl;
    cout<<"age : "<<p.age<<endl;
}


int main(void){
    Person p("minwoo",23);
    ShowPersonInfo(p);
    return 0;
}

 

위 경우도 ShowPersonInfo에 인자로 전달한 객체가 p라는 변수에 담기게 된다.

Person p가 참조형(Call-by-reference)이 아닌 일반적인 변수이기 때문에 Person p에 인자로 전달된 p를 임시로 복사하여 대입하게 된다.

결론적으로 함수 내의 p와 인자로 전달한 p의 주소값은 다르다.

 

 

3. 객체를 참조형이 아닌 타입으로 반환하는 경우

Person GetPerson(Person &p){ // call-by-refernece라서 인자에서는 복사 생성자 X
	return p; // 반환 과정에서 임시 객체에 복사하여 반환.
}

 

위 예시에서는 인자로는 참조형이 사용되어 값을 복사하는 것이 아닌 그 주소값에 또 하나의 별칭이 생기는 방식이다.

하지만 반환형이 기본 Person이기 때문에 임시 객체에 p를 복사하여 그 값을 반환하게 된다.

따라서 반환 과정에서 복사 생성자가 호출되게 된다.

 

 

대입 시에 복사생성자가 호출되지 않게 하려면 ?

우리는 위에서 객체 간의 대입중에 복사생성자가 실행된다는 것을 보았다.

 

Person p1("minwoo",23);
Person p2 = p1;

위 코드가

Person p1("minwoo",23);
Person p2(p1);

이처럼 변경되어 실행되는 것이다.

하지만, 대입을 할 때 복사 생성자가 실행되는 걸 원치 않는 상황도 있을 것이다.

 

이럴 때, 복사 생성자의 앞에 explicit 키워드를 붙인다면 컴파일러가 자동으로 변환하는 것을 막는다.

 

즉, p2(p1) 과 같은 형식으로 작성해야만 복사 생성자가 실행된다는 말이다.

 

728x90
반응형
LIST