C++_8주차_정리

728x90

*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;
}

728x90

'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