본문 바로가기

강의자료/Class

008. 다형성에서 객체복사를 위한 가상복사생성자를 만들자.

◈ 이 글은 강의를 위하여 제가 직접 작성한 내용입니다. 따라서 퍼가실 경우, 출처를 명확히 해주시기 바랍니다!!
◈ This ariticle was written by me for teaching. So if you want to copy this article, please clarify the source!!



이제 다형성을 이용하는 방법을 알았다.
하지만, 다형성을 이용하면서 객체를 복사하기 위해서는 일반적인 복사생성자로는 불가능하다.
다형성을 이용할 때 객체를 복사할 수 있도록 해주는 가상복사생성자에 대해 알아보자.
// 일반함수를 위한 함수 오버라이딩은 이름만 같으면 된다.
// 가상함수를 위한 함수 오버라이딩은 반드시 입력과 출력 선언이 모두 일치해야 한다.
// 단, 자기자신의 포인터를 리턴하는 경우에 한해서만, 예외적으로 출력타입이 달라도 된다.
//    (출력타입에는 부모 또는 부모를 상속받은 타입만 적용가능하다.)

#include 
using namespace std;

class Mammal
{
public:
	Mammal() : itsAge(1) {}
	virtual ~Mammal() {}
	
	virtual void Speak() const 
	{ 
		cout << "Mammal speak!\n"; 
	}

	Mammal(const Mammal& rhs) : itsAge(rhs.itsAge) {}
	virtual Mammal* Clone() { return new Mammal(*this); }

protected:
	int itsAge;
};

class Dog : public Mammal
{
public:
	void Speak() const { cout << itsSpeed << " -> Woof!\n";}

	Dog(int speed) : itsSpeed(speed) {}
	Dog(const Dog& rhs) : Mammal(rhs), itsSpeed(rhs.itsSpeed) {}
	//Dog(const Mammal& rhs) : Mammal(rhs), itsSpeed(rhs.itsSpeed) {}	// Mammal에는 itsSpeed가 없으므로 실패.

	//virtual Mammal* Clone() { return new Dog(*this); }	// 코드는 가능하지만, Dog를 복사하여 Dog에게 넘겨주지 못하고 오로지 Mammal에게만 넘겨줄 수 있으므로 사용하지 않는다.
	virtual Dog* Clone() { return new Dog(*this); }			// Dog를 복사한 후, Dog와 Mammal 모두에게 넘겨줄 수 있다.

private:
	int itsSpeed;
};

void main()
{
	Mammal* ptr = new Dog(5);
	ptr->Speak();

	//Mammal* ptr2 = new Dog(*ptr);		// 타입불일치로 불가능.
	//Mammal* ptr2 = new Dog(*ptr);		// 생성자를 직접 만들더라도 itsSpeed값을 읽어올 수 없으므로 실패.
	//Mammal* ptr2 = new Mammal(*ptr);	// Mammal부분만 복사되므로 실패.
	Mammal* ptr2 = ptr->Clone();
	ptr2->Speak();

	Dog* pDog = new Dog(10);
	Dog* pDog2 = new Dog(*pDog);
	pDog2->Speak();
	Dog* pDog3 = pDog->Clone();			// virtual Mammal* Clone()코드를 이용할 경우, 여기서 에러가 발생한다.
	pDog3->Speak();
}