2011-04-20 1 views
22

나는 오랫동안 이런 종류의 문제로 어려움을 겪어 왔기 때문에 여기서 물어보기로했다.파생 클래스 인스턴스를 포인터에서 다형 기본 클래스로 복사/작성하는 방법은 무엇입니까?

class Base { 
    virtual ~Base(); 
}; 
class Derived1 : public Base { ... }; 
class Derived2 : public Base { ... }; 
... 

// Copies the instance of derived class pointed by the *base pointer 
Base* CreateCopy(Base* base); 

이 방법은 동적으로 생성 된 복사본을 반환 또는 적어도 문제 "임시 주소를 반환하는"피하기 위해 일부 데이터 구조 스택의 객체를 저장한다.

위의 방법을 구현하는 순진한 접근법은 일련의 if 문에서 복수 typeid 또는 dynamic_cast을 사용하여 가능한 파생 형식을 확인한 다음 new 연산자를 사용하는 것입니다. 더 좋은 방법이 있습니까?

P .: 필자는 스마트 포인터를 사용하여이 문제를 피할 수 있음을 알고 있습니다. 그러나 라이브러리가 없어도 최소한의 접근 방식에 관심이 있습니다.

+1

이 질문의 정확한 복제본 같습니다 : http://stackoverflow.com/questions/5148706/copying-a-polymorphic-object-in-c. 마이클 앤더슨 (Michael Anderson)의 답변을 확인하십시오. – Darhuuk

+1

@Darhuuk : 중복에 대한 SO 정책이 무엇인지는 잘 모르겠지만이 질문은 조금 다릅니다. 여기서 OP는이 문제를 해결하는 방법에 대해 물었고, 그 질문의 OP는 복제가 좋은 C++ 접근법인지 여부를 묻습니다. 분명히 관련이 있습니다. 정확한 복제인지 확실하지 않습니다. – ltjax

+0

@Itjax 충분히 공정한 것은, 거기에 주어진 답은 OP가 찾고있는 것보다 다소 정확하다는 것입니다. 비록 내가 당신의 대답은 훨씬 더 편리합니다 :). – Darhuuk

답변

34

기본 클래스에 virtual Base* clone() const = 0;을 추가하고 파생 클래스에서 적절하게 구현합니다. Base이 추상적이지 않은 경우에는 물론 복사 생성자를 호출 할 수 있지만 이는 약간 위험합니다. 파생 클래스에서 구현하는 것을 잊어 버리면 (아마도 원치 않는) 조각을 얻을 수 있습니다. 당신이 그 코드를 복제 할 수없는 경우

, 당신은 템플릿을 통해 기능을 구현하기 위해 CRTP idiom를 사용할 수 있습니다

template <class Derived> 
class DerivationHelper : public Base 
{ 
public: 
    virtual Base* clone() const 
    { 
    return new Derived(static_cast<const Derived&>(*this)); // call the copy ctor. 
    } 
}; 

class Derived1 : public DerivationHelper <Derived1> { ... }; 
class Derived2 : public DerivationHelper <Derived2> { ... }; 
+4

+1 : 표준 방식입니다. –

1

또 다른 공통베이스 순수 가상 CreateCopy() 방법을 가지고하는 것입니다 파생 된 각 클래스에서 구현됩니다.

+0

다음과 같은 의미입니까? http://ideone.com/FlQ9LF? –

+0

@David Doria : 스 니펫이 메모리를 크게 누출한다는 점을 제외하고는 가볍게 누르십시오. – sharptooth

관련 문제