2012-06-27 2 views
1

이 모든 것이 간단한 문제인 것처럼 보일뿐입니다. 내가 C++ 기본 클래스를 Animal이라고하고 Cat, Dog, Horse, Hippo, Snake 클래스를 파생했다고 가정 해 보겠습니다. Zoo라는 또 다른 클래스가 있습니다. 여기에는 Animal 객체의 기본 클래스 Animal이 QObject 인 목록 (이 경우 Qt List)이 포함되어 있습니다. 이제는 동물원 객체를 만들어 다른 동물원 객체에 복사하고 대상 동물원에 자신의 동물 사본을 만들 수있게하려고합니다. 문제는 동물원 복사 생성자에 있습니다. 왜냐하면 컴파일러가해야하는 것처럼 Dog, Cat 등 대신 Animal 용 복사 생성자를 호출하는 Animals 목록이 있다고 생각하기 때문입니다. 이 문제를 해결하기 위해 Animal 목록을 Animal 포인터 목록으로 변경 한 다음 내 자신의 Animal 복사 생성자와 할당 연산자를 만들었습니다. 이들 각각은 Animal :: Clone (Animal & rhs) 메서드를 호출하며,이 메서드는 차례로 해당 데이터 복사본이있는 힙에서 할당 된 새 포인터를 반환하는 Animals Clone() 메서드의 파생 클래스를 호출합니다. 이 모든 것은 잘 작동하지만 더 우아한 솔루션이 없다고 생각하고 있습니다. 그래서 내 질문은, 당신이 유형의 개체를 가진 컨테이너를 가지고 우리가 어떻게 컨테이너를 포함하는 클래스를 복사합니까? 나는 그것이 의미가 있기를 바랍니다.상속을 사용하는 컨테이너의 컨테이너 복사본

+2

'Animal' 가상에 대한 복사 생성자를 만들려고 했습니까? – Daniel

+0

나는 부모 함수의 함수를 가상 함수로 재정의하는 유일한 방법 인 Daniel에 동의합니다. 그렇지 않으면 컴파일러에서 생성되는 코드가 생깁니다. –

+0

Animal에서 QObject를 상속하면 문제가 발생합니다. Qt가 올바르게 이해하면 QObject에서 상속 한 객체의 복사본을 사용할 수 없습니다. 그게 정확한지 아무도 알지 못합니까? – Brad

답변

2

당신이 한 일은 거의 입니다. C++에서 그것을하는 관용적 인 방법입니다. 가상 clone() 메서드는 사실상 가상 복사본 생성자 idiom으로 알려져 있습니다. 일반적으로 다음 서명의 가상 추상 메서드로 선언합니다.

Animal * clone() const = 0; 

매개 변수는 rhs이 아니며 단순히 복제본을 반환합니다. 동물 Animal * myPet의 인스턴스을 감안할 때, 당신은 그들이 인스턴스화 할 경우 당신은 파생 클래스에서 구현 수밖에

Animal * mySecondPet = myPet->clone(); 

말함으로써 중복을 얻을 수 있습니다.

[에드 :] 당신이 발견 한 것처럼 컨테이너 클래스 인해 C의 디자인에 slicing problem 고유에, 포인터를 통해 직접이 아닌 항목을 보관하는 데에 대한, 그것은 ++ 불가능하다.

C++에서 해결책은 관용구입니다. 즉, 얻는 것만 큼 우아하며, C++을 알고있는 모든 사람이 사용자의 뜻을 즉시 알아야합니다. 숙어 및 특정 디자인 패턴은 언어의 일부입니다. 숙어를 모르고서도 인간 이건 프로그래밍 이건 언어에 능숙하지 못합니다.

많은 프로젝트에서이 복제 메서드로만 구성된 Cloneable이라는 인터페이스 클래스 (모든 추상 가상 메서드)를 사용합니다. Cloneable에서 상속받은 클래스를 쉽게 적용 할 수 있습니다. 예를 들어, QEventCloneable입니다. 그렇기 때문에 QEvents을 복제하여 여러 이벤트 대기열에 게시하는 것은 불가능합니다.

Daniel의 제안 "Animal Virtual의 복사본 생성자를 만들려고 했습니까?" 문자 그대로 받아 들일 수 없다. 단순한 이유 때문에 가상 복사본 생성자 또는 모든 생성자와 같은 것은 없습니다. 개체가 생성되기 전에 가상 메서드 테이블이 마무리되지 않습니다. 특히 Animal 생성자의 코드는 파생 클래스의 생성자가 호출되어 가상 메서드 테이블 포인터를 파생 클래스의 포인터로 스왑 아웃하기 전에 실행됩니다. 따라서 생성자에서 가상 메서드 호출을 만든 경우 클래스에서 파생 된 클래스로 이동하지 않습니다. 그게 전부 야.

+0

그건 의미가 있습니다. 그리고 나서 Zoo 클래스에서 각 Animal의 clone() 메소드를 호출하는 QList를 순환하도록 복사 생성자와 대입 연산자를 구현 하시겠습니까? – Brad

+0

맞습니다. –

관련 문제