[c++] 포인터 멤버 변수 깊은 복사하기

숭글·2023년 1월 18일
0
post-custom-banner
class Note{
	public :
		Note();
		Note(Note &obj);
		Note& operator=(Note &obj);
		std::string		getList(int idx) const;
		void			setList(int idx, std::string str);
		~Note();
		
	private : 
		std::string lists[5];
};

배열을 멤버 변수로 가진 Note클래스이다.
복사 생성자와 대입 연산자가 구현돼있다.

Note::Note(Note &obj){
	for (int i = 0; i < 5; ++i)
		ideas[i] = obj.lists[i];
}

Note& Note::operator=(Note &obj){
	std::cout << "Note's Assignment Operator" << std::endl;
	for (int i = 0; i < 5; ++i)
		ideas[i] = obj.lists[i];
	
	return (*this);
}

깊은 복사를 위해 배열의 주소가 아닌 원소를 대입한다.

class Bag{
	public : 
		Bag();
		Bag(Bag& obj);
		Bag& operator=(Bag& obj);
		Note *getNote(){
			return (note);
		};
	
	private : 
		Note *note;
};

Note의 포인터를 맴버 변수로 갖는 Bag클래스이다.

Bag::Bag(Bag& obj){
	note = new Note();
	note = obj.note; ❌
	std::cout << "create Bag" << std::endl;
}

Bag& Bag::operator=(Bag& obj){
	note = obj.note;return (*this);
}

위처럼 복사 생성자와 대입 연산자를 구현하면 note는 얕게 복사되게 된다.
note가 그냥 Note타입이 아닌 Note 포인터 타입이기 때문이다!!

int main(){

	Bag *i = new Bag();
	Bag *j = new Bag(*i);

	std::cout << "before : " << i->getNote()->getNoteList(0) << std::endl;
	std::cout << "before : " << j->getNote()->getNoteList(0) << std::endl;
	
	i->getNote()->setNoteList(0, "Go home");

	std::cout << "after : " << i->getNote()->getNoteList(0) << std::endl;
	std::cout << "after : " << j->getNote()->getNoteList(0) << std::endl;

	return 0;
}

output >

before : ...
before : ...
after : Go home
after : Go home

실제로 얕은 복사가 된 것을 확인할 수 있다.

Bag클래스의 복사 생성자와 대입 연산자에서도 Note클래스와 마찬가지로 원소를 복사하여(getter, setter를 이용) 깊은 복사를 할 수도 있겠지만 이미 Note클래스에서 깊은 복사를 구현해뒀기때문에 또 하기엔 너무 너무 아깝다......!

포인터 타입의 멤버 변수(타입의 클래스 내부에서 깊은 복사가 구현돼있는 경우)를 깊은 복사하기 위해선 포인터를 이용하면 된다!!

Bag::Bag(Bag& obj){
	note = new Note();
	*note = *obj.note;
	std::cout << "create Bag" << std::endl;
}

Bag& Bag::operator=(Bag& obj){
	*note = *obj.note;
	
	return (*this);
}

크게 달라진 점은 없지만
포인터를 이용하면 Note의 대입 연산자를 호출하여 복사를 진행하게 된다.

output >

Note's Assignment Operator
before : ...
before : ...
after : Go home
after : ...

깊은 복사가 된 것을 확인할 수 있다!

profile
Hi!😁 I'm Soongle. Welcome to my Velog!!!
post-custom-banner

0개의 댓글