미누에요
[C++] 복사 생성자 (Copy Constructor) 본문
복사 생성자는 "="을 사용화여 연산을 수행하는 경우에 자동적으로 실행된다.
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 ©):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) 과 같은 형식으로 작성해야만 복사 생성자가 실행된다는 말이다.
'C++' 카테고리의 다른 글
[C++] static, 클래스 안에서의 static (0) | 2024.06.28 |
---|---|
[C++] friend (0) | 2024.06.28 |
[C++] malloc과 new 의 차이점 (0) | 2024.06.25 |
[C++] 문자열을 나타내는 방식, const char*, char*, string (0) | 2024.05.25 |
[C++] 윤성우의 열혈 C++ 11-2 C++ 기반의 데이터 입출력 문제풀이 (1) | 2024.05.21 |