자료 저장소

# 복사생성자

객체와 객체간의 대입시 멤버대 멤버의 복사가 일어나는데 이때 호출되는것이 복사생성자이다.
복사생성자를 정의하지 않으면, 기본적으로 멤버대 멤버복사가 가능한 디폴트 복사생성자가 자동으로 삽입된다.
복사생성자의 매개변수 선언에 const는 원본의 변경을 막기 위해 사용되며 참조형의 선언을 의미하는 &연산자는
반드시 삽입되어야 한다.


# 얕은복사와 깊은복사

디폴트 복사생성자의 경우 얕은 복사(shallow copy)를 하는 문제점이 있다.
이는 멤버변수가 힙의 메모리 공간을 참조하는 경우에 발생하는데 복사된 멤버가 완전히 별개의 메모리를
소유하는 것이 아닌,원본의 메모리 공간을 참조해버리기 때문이다.
class student 
{
private:
char *name;
public:
student() {} // 디폴트 생성자

student(char *name) // 생성자 정의
{
this->name=newchar[strlen(name)+1];
strcpy(this->name,name);
}

student(student &pStd) // 복사생성자(깊은복사)
{
name=newchar[strlen(pStd.name)+1];
strcpy(name,pStd.name);
}

~student() { delete []name; }
};

메모리 공간할당 후 문자열을 복사를 위해 할당된 메모리의 주소값을 멤버 name에 저장하고있다.
힙 메모리를 사용하는 경우 깊은 복사를 하는 복사생성자를 반드시 작성하여야 한다.


# 복사생성자의 호출시점

- case 1 : 기존에 생성된 객체를 이용해서 새로운 객체를 초기화 하는 경우
ex) student p1 = p2; // p1의 메모리 공간 할당(생성자 호출) 및 p2의 값을 복사 하기 위해 복사생성자 호출.

- case 2 :  Call-by-value 방식의 함수호출 과정에서 객체를 인자로 전달하는 경우
ex) void func(student temp); func(p2); // temp로 복사되는 순간 p2의 값의 복사를 위해 복사생성자 호출.

- case 3 : 객체를 반환하되, 참조형으로 반환하지 않는 경우
ex) student func(student p1) { return p1; }
// return문이 실행되는 순간 student 객체를 위한 메모리 공간이 할당되고 이 공간에 반환되는 객체 p1의
내용으로 초기화된다.(복사생성자 호출)


※ case 3의 경우 반환을 위해 임시객체(temporary object)가 생성된다. 이 객체는 메모리 공간에 존재하고,
다음 행으로 넘어갈 경우 소멸된다. 하지만 참조자를 통해 참조되는 임시객체의 경우는 바로 소멸되지 않는다.

댓글 로드 중…

최근에 게시된 글