이 모든 것이 간단한 문제인 것처럼 보일뿐입니다. 내가 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() 메서드의 파생 클래스를 호출합니다. 이 모든 것은 잘 작동하지만 더 우아한 솔루션이 없다고 생각하고 있습니다. 그래서 내 질문은, 당신이 유형의 개체를 가진 컨테이너를 가지고 우리가 어떻게 컨테이너를 포함하는 클래스를 복사합니까? 나는 그것이 의미가 있기를 바랍니다.상속을 사용하는 컨테이너의 컨테이너 복사본
답변
당신이 한 일은 거의 입니다. C++에서 그것을하는 관용적 인 방법입니다. 가상 clone()
메서드는 사실상 가상 복사본 생성자 idiom으로 알려져 있습니다. 일반적으로 다음 서명의 가상 추상 메서드로 선언합니다.
Animal * clone() const = 0;
매개 변수는 rhs
이 아니며 단순히 복제본을 반환합니다. 동물 Animal * myPet
의 인스턴스을 감안할 때, 당신은 그들이 인스턴스화 할 경우 당신은 파생 클래스에서 구현 수밖에
Animal * mySecondPet = myPet->clone();
말함으로써 중복을 얻을 수 있습니다.
[에드 :] 당신이 발견 한 것처럼 컨테이너 클래스 인해 C의 디자인에 slicing problem 고유에, 포인터를 통해 직접이 아닌 항목을 보관하는 데에 대한, 그것은 ++ 불가능하다.
C++에서 해결책은 관용구입니다. 즉, 얻는 것만 큼 우아하며, C++을 알고있는 모든 사람이 사용자의 뜻을 즉시 알아야합니다. 숙어 및 특정 디자인 패턴은 언어의 일부입니다. 숙어를 모르고서도 인간 이건 프로그래밍 이건 언어에 능숙하지 못합니다.
많은 프로젝트에서이 복제 메서드로만 구성된 Cloneable
이라는 인터페이스 클래스 (모든 추상 가상 메서드)를 사용합니다. Cloneable에서 상속받은 클래스를 쉽게 적용 할 수 있습니다. 예를 들어, QEvent
은 Cloneable
입니다. 그렇기 때문에 QEvents
을 복제하여 여러 이벤트 대기열에 게시하는 것은 불가능합니다.
Daniel의 제안 "Animal Virtual의 복사본 생성자를 만들려고 했습니까?" 문자 그대로 받아 들일 수 없다. 단순한 이유 때문에 가상 복사본 생성자 또는 모든 생성자와 같은 것은 없습니다. 개체가 생성되기 전에 가상 메서드 테이블이 마무리되지 않습니다. 특히 Animal 생성자의 코드는 파생 클래스의 생성자가 호출되어 가상 메서드 테이블 포인터를 파생 클래스의 포인터로 스왑 아웃하기 전에 실행됩니다. 따라서 생성자에서 가상 메서드 호출을 만든 경우 클래스에서 파생 된 클래스로 이동하지 않습니다. 그게 전부 야.
그건 의미가 있습니다. 그리고 나서 Zoo 클래스에서 각 Animal의 clone() 메소드를 호출하는 QList를 순환하도록 복사 생성자와 대입 연산자를 구현 하시겠습니까? – Brad
맞습니다. –
- 1. OOP 디자인 문제 : 컨테이너 또는 컨테이너의 책임?
- 2. JPA 상속을 사용하는 방법
- 3. 봉쇄 상속을 사용하는 애니메이션
- 4. 상속을 사용하는 작성자 패턴
- 5. 방문자를 사용하는 동안 컨테이너 변경
- 6. 상속을 사용하는 엔티티에 대한 SQL
- 7. 클래스 상속을 사용하는 WCF 서비스
- 8. Nib 파일과 상속을 사용하는 UIViewController
- 9. 일반 유형 상속을 사용하는 AutoMapper
- 10. iOS SDK에서 상속을 사용하는 방법
- 11. 다중 상속을 사용하는 XML 스키마
- 12. 개체 상속을 사용하는 WCF 직렬화?
- 13. 컨테이너의 높이가 auto 일 때 컨테이너 div의 div와 height를 중첩합니다.
- 14. 해당 컨테이너 내의 요소로 컨테이너의 높이를 정의하는 방법
- 15. 제어 컨테이너의 다중 반전 대 "1 대 1"컨테이너
- 16. jQuery를 사용하는 컨테이너를 제외한 컨테이너의 모든 div를 사라지게하는 방법은 무엇입니까?
- 17. 상속을
- 18. div 컨테이너의 경계를 벗어납니다.
- 19. H264 -> .NET을 사용하는 컨테이너
- 20. 복잡한 레이아웃을 사용하는 컨테이너 제거
- 21. 다중 상속을 사용하는 C++ LinkedList 템플릿?
- 22. 구현을 숨기려면 개인 상속을 사용하는 것이 좋습니까?
- 23. 엔티티 프레임 워크 상속을 사용하는 방법?
- 24. devise : instance 단일 테이블 상속을 사용하는 current_user
- 25. 상속을 사용하는 클래식 ASP 클래스 속성
- 26. WPF의 DataBinding에서 상속을 효과적으로 사용하는 방법은 무엇입니까?
- 27. Boost :: 상속을 사용하는 클래스에 대한 파이썬 바인딩
- 28. 상속을 사용하는 표준화 된 양식 C#
- 29. 엔티티 프레임 워크 상속을 사용하는 Automapper
- 30. android에서 다중 레벨 상속을 사용하는 방법
'Animal' 가상에 대한 복사 생성자를 만들려고 했습니까? – Daniel
나는 부모 함수의 함수를 가상 함수로 재정의하는 유일한 방법 인 Daniel에 동의합니다. 그렇지 않으면 컴파일러에서 생성되는 코드가 생깁니다. –
Animal에서 QObject를 상속하면 문제가 발생합니다. Qt가 올바르게 이해하면 QObject에서 상속 한 객체의 복사본을 사용할 수 없습니다. 그게 정확한지 아무도 알지 못합니까? – Brad