*Copy Constructor 복사 생성자
CodeNum ModelNum SerialNum
SStv 101 10131 101551
LGtv 102 10242 102341
HDtv 103 10354 103423
GStv 104 10423 104311
얕은 복사 (=Shallow Copy)와 깊은 복사(= Deep Copy)
복사하는 방법에는
얕은 복사, 깊은 복사 두 가지 방법이 있다.
얕은 복사 : 말 그대로 일반 변수의 값은 그대로 복사하고
포인터 변수의 주소값도 그대로 복사한다.
-> 그래서 서로 다른 두 포인터 변수들이
같은 주소를 공유하게 된다
-> 그래서 하나의 포인터 변수가 정보를 수정하면
다른 포인터 변수의 정보도 따라서 수정이 된다 (문제)
깊은 복사 : 복사 생성자(=Copy Consturctor)를 사용하는 방법으로
일반 변수의 값은 그대로 복사하되,
포인터 변수의 경우에는 , 새 메모리 공간 확보한 뒤에
주소값이 가리키는 장소의 내용을 복사한다.
-> 그래서 완벽히 독립적인 형태로 복사가 된다.
프로그램이 비정상적으로 실행되는 경우
Television GStv;
GStv = SStv; (X) //(=) 대입 연산자로 객체 copy 시도할 경우
문제가 발생한다.
프로그램이 정상적으로 실행되도록 하기 위해서는
복사 생성자(Copy Constructor) 사용해야 한다.
객체 생성 부분에서 복사 생성자를 사용하여 다음과 같이 선언해야 한다.
Television GStv (SStv); (O) //객체 생성자에 객체 복사하는 ‘복사 생성자’
//8주차 수업
#include <iostream>
#include <string>
using namespace std;
class Television {
//멤버변수
private:
int inch; //화면 크기 : 유효범위는 [1~50]
int channel; //채널 번호 : 유효범위는 [1~100]
int volume; //소리 크기 : 유효범위는 [0~100]
int* brand; //[0] = code, [1] = model, [2] = serial
//멤버함수들
public:
//생성자 -(1) : 매개변수 없는 생성자
Television() {
inch = 50;
channel = 10;
volume = 0;
brand = new int[3]; //new 동적 메모리 할당 방식으로 정수형 공간 3개 받는다.
brand[0] = 101;
brand[1] = 10131;
brand[2] - 101551;
}
//생성자 -(2) : 매개변수 있는 생성자
Television(int pInch, int pChannel, int pVolume, int pCode, int pModel, int pSerial) {
inch = pInch;
channel = pChannel;
pVolume = pVolume;
brand = new int[3];
brand[0] = pCode;
brand[1] = pModel;
brand[2] = pSerial;
}
//복사 생성자 = Copy Constructor
Television(Television& T) { //포인터 개념으로 해당 객체의 주소를 받아온다 .
inch = T.inch;
channel = T.channel;
volume = T.volume;
//내부 배열값의 경우 공간 확보 후 -> 옮겨준다.
brand = new int[3];
brand[0] = T.brand[0];
brand[1] = T.brand[1];
brand[2] = T.brand[2];
}
//소멸자
~Television() {
}
int GetInch() {
return inch;
}
void SetInch(int pInch) {
inch = pInch;
}
int GetChannel() {
return channel;
}
void SetChannel(int pChannel) {
channel = pChannel;
}
int GetVolume() {
return volume;
}
void SetVolume(int pVolume) {
volume = pVolume;
}
int GetBrandCodeNumber() {
return brand[0];
}
void SetBrandCodeNumber(int pCode) {
brand[0] = pCode;
}
int GetBrandModelNumber() {
return brand[1];
}
void SetBrandModelNumber(int pModel) {
brand[1] = pModel;
}
int GetBrandSerialNumber() {
return brand[2];
}
void SetBrandSerialNumber(int pSerial) {
brand[2] = pSerial;
}
};
int main() {
Television SStv, LGtv;
Television HDtv(30, 3, 0, 103, 10354, 103423);
Television GStv;
Television SKtv(LGtv); //SKtv는 LGtv 정보를 복사하여 객체를 생성하는 '복사생성자' 이용
cout << "SStv: " << endl;
cout << "Inch = " << SStv.GetInch()
<< ", Channel = " << SStv.GetChannel()
<< ", Volume = " << SStv.GetVolume()
<< ", Code Number = " << SStv.GetBrandCodeNumber()
<< ", Model Number =" << SStv.GetBrandModelNumber()
<< ", Serial Number = " << SStv.GetBrandSerialNumber()
<< endl;
cout << endl;
cout << "LGtv: " << endl;
cout << "Inch = " << LGtv.GetInch()
<< ", Channel = " << LGtv.GetChannel()
<< ", Volume = " << LGtv.GetVolume()
<< ", Code Number = " << LGtv.GetBrandCodeNumber()
<< ", Model Number =" << LGtv.GetBrandModelNumber()
<< ", Serial Number = " << LGtv.GetBrandSerialNumber()
<< endl;
cout << endl;
cout << "HDtv: " << endl;
cout << "Inch = " << HDtv.GetInch()
<< ", Channel = " << HDtv.GetChannel()
<< ", Volume = " << HDtv.GetVolume()
<< ", Code Number = " << HDtv.GetBrandCodeNumber()
<< ", Model Number =" << HDtv.GetBrandModelNumber()
<< ", Serial Number = " << HDtv.GetBrandSerialNumber()
<< endl;
GStv = SStv; //SStv 내용을 GStv에 복사 <문제>
cout << endl;
cout << "GStv: " << endl;
cout << "Inch = " << GStv.GetInch()
<< ", Channel = " << GStv.GetChannel()
<< ", Volume = " << GStv.GetVolume()
<< ", Code Number = " << GStv.GetBrandCodeNumber()
<< ", Model Number =" << GStv.GetBrandModelNumber()
<< ", Serial Number = " << GStv.GetBrandSerialNumber() << endl;
//이 상태에서 원본 SStv 내부 변환 시도
SStv.SetBrandCodeNumber(108);
SStv.SetBrandModelNumber(10867);
SStv.SetBrandSerialNumber(108567);
cout << "SStv: " << endl;
cout << "Inch = " << SStv.GetInch()
<< ", Channel = " << SStv.GetChannel()
<< ", Volume = " << SStv.GetVolume()
<< ", Code Number = " << SStv.GetBrandCodeNumber()
<< ", Model Number =" << SStv.GetBrandModelNumber()
<< ", Serial Number = " << SStv.GetBrandSerialNumber()
<< endl;
//근데 이 상태에서 GStv 내부도 SStv의 변환된 내용을 그대로 담고 있음 (즉, 함께 변함)
//SS만 건들였는데 손대지 않은 GS까지 변한거다 GS는 분명 변환 이전에 복사했을 뿐인데... --> 얕은 복사(포인터까지)
cout << endl;
cout << "GStv: " << endl;
cout << "Inch = " << GStv.GetInch()
<< ", Channel = " << GStv.GetChannel()
<< ", Volume = " << GStv.GetVolume()
<< ", Code Number = " << GStv.GetBrandCodeNumber()
<< ", Model Number =" << GStv.GetBrandModelNumber()
<< ", Serial Number = " << GStv.GetBrandSerialNumber() << endl;
//이 문제 해결을 위해 Copy Constructor 이용하여 '복사 생성자' 사용 할 거다
getchar();
getchar();
return 0;
}
'C++, C언어 > [문법]_C++' 카테고리의 다른 글
C++_10주차_정리 (0) | 2021.12.20 |
---|---|
C++_9주차_정리 (0) | 2021.12.20 |
C++_7주차_정리 (0) | 2021.12.20 |
C++_6주차_정리 (0) | 2021.12.20 |
C++_5주차_정리 (0) | 2021.12.20 |