카테고리 없음
C++ 복사 생성자, 복사 대입 연산자 (깊은 복사)
chogyujin
2022. 7. 20. 00:19
728x90
C++은 클래스 생성시 컴파일러가 자동으로 생성자, 소멸자, 복사 생성자, 복사 대입 연산자 이렇게 4가지가 있습니다.
복사 생성자와 복사 대입 연사자란?
복사 생성자는 객체의 복사를 생성할 때 호출되는 생성자입니다.
복사 대입 연산자는 같인 타입의 객체를 이미 생성되어 있는 객체에 값을 복사할 때 사용됩니다.
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<memory>
using namespace std;
class SuperCar
{
private:
int a;
char* s;
public:
SuperCar(int num, const char* c) : a(num)
{
s = new char[strlen(c)];
strcpy(s, c);
cout << "기본 생성자" << endl;
}
SuperCar(const SuperCar& S)
{
a = S.a;
s = new char[strlen(S.s)];
strcpy(s, S.s);
cout << "복사 생성자" << endl;
}
SuperCar& operator=(const SuperCar& S)
{
if (this != &S)
{
a = S.a;
s = new char[strlen(S.s)];
strcpy(s, S.s);
cout << "복사 대입 연산자" << endl;
}
return *this;
}
void Open()
{
cout << "위로 열림" << endl;
}
~SuperCar()
{
cout << "슈퍼카 해제" << endl;
}
};
int main()
{
SuperCar s(1,"cbs");//기본 생성자
SuperCar s1(2,"wbs");//기본 생성자
SuperCar s2 = s1; // 복사 생성자
s = s1; // 복사 대입 연산자
return 0;
}
객체를 생성함과 동시에 다른 객체를 복사하면 복사 생성자가 호출되고 이미 생성되어 있는 객체에 다른 객체를 복사하면
복사 대입 연산자가 호출됩니다. 복사 대입 연산자의 return 형을 A& 이렇게 참조형을 return 하는 이유는 s=s1=s2 연속으로 대입 연산자가 호출이 가능하도록 하기 위함입니다.
단 이렇게 정의를 하지 않을경우 컴파일러는 자동으로 디폴트 생성자들을 만들어주는데 이는 다 얕은 복사를 해줍니다.
얕은 복사란?
얕은 복사는 객체가 가진 맴버들의 값을 새로운 객체로 복사하는데 만약 복사 대상객체가 참조타입의 맴버를 가지고
있다면 참조값만 복사가 됩니다. 그러므로 참조타입의 값이 변경될 경우 해당 객체로 복사한 모든 객체들의 값이
일괄 변경되는 문제가 발생합니다.
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<memory>
using namespace std;
class SuperCar
{
public:
int a;
char* s;
SuperCar(int num, const char* c) : a(num)
{
s = new char[strlen(c)];
strcpy(s, c);
cout << "기본 생성자" << endl;
}
void print()
{
cout << a << " " << s<<endl;
}
void Open()
{
cout << "위로 열림" << endl;
}
~SuperCar()
{
cout << "슈퍼카 해제" << endl;
}
};
int main()
{
SuperCar s(1,"cbs");
SuperCar s1(s);
s1.a = 20;
strcpy(s1.s, "qqqqqqq");
s.print();
s1.print();
return 0;
}
cbs에서 qqqqqq로 변경되는 것을 볼수 있습니다.
얕은 복사로 인해 char* s을 여러 객체어서 같이 참조하기 떄문에 발생하는 문제입니다.