이미 생성된 객체로부터 값을 복사해 같은 값, 타입의 객체를 만들때
우리는 다음과 같은 형식의 생성자를 이용한다
#include <string.h>
#include <stdio.h>
#pragma warning(disable:4996)
class Human
{
private:
char name[12];
int age;
public:
Human(const char* aname, int aage)
{
strcpy(name, aname);
age = aage;
}
void intro() {
printf("이름=%s,나이 =%d\n", name, age);
}
};
int main()
{
Human kim("woogie", 26);
kim.intro();
Human Lee = kim; //복사 생성자 사용
Lee.intro();
return 0;
}
복사 생성자의 경우 없을 경우 컴파일러가 디폴트 생성자를 자동으로 만들어 주기 때문에 위와 같은 예제도 잘 작동한다. 하지만 디폴트 복사 생성자를 이용한 사본 객체 생성은 일대일 복사만을 수행하기 때문에 위험하다.
컴파일러를 통해 생성되는 디폴트 복사 생성자의 내부는 다음과 같은 구조다.
Human(const Human& other)
{
strcpy(name, other.name);
age = other.age;
}
위와 같은 디폴트 생성자는 단순히 일대일 대응을 할 뿐이어서 객체가 포인터기반의 변수를 가지는 경우 완전히 독립된 객체가 아니라 한 가지 변수를 공유하게 된다. (같은 address를 지목)
이런 식으로 address를 공유하게 되면 한 객체가 파괴될 때 남아있는 변수의 멤버도 함께 파괴된다는 점이다.
포인터를 가진 클래스는 완전히 독립된 복사 객체를 가지기 위해서는 별도의 복사생성자 작성이 필요하다.
#include <stdio.h>
#include <string.h>
class Human
{
private :
char *pname;
int age;
public :
Human(const char* aname, int aage) {
pname = new char[strlen(aname) + 1];
strcpy(pname, aname);
age = aage;
}
Human(const Human& other) {
pname = new char[strlen(other.pname) + 1]; //동적할당을 거쳐 깊은 복사 수행
strcpy(pname, other.pname);
age = other.age;
}
};
'Language > C++' 카테고리의 다른 글
Has A 관계를 표현하는 클래스 활용 기법 - 포함(Containment) (0) | 2021.02.22 |
---|---|
정적 멤버 변수, 함수 (0) | 2021.02.15 |
int 변수의 앞자리가 0인 경우, 0123 = 83 ? Int prefix (0) | 2021.02.03 |
Vector - Array와의 차이점과 쓰임새 (0) | 2021.01.22 |
vector 사용 시 []연산자와 at() 멤버 함수의 차이 (0) | 2021.01.21 |