2010-06-28 3 views
5

여기 (이 코드는 작동하지 않습니다) 내가 할 노력하고있어입니다 :파생 된 C++ 클래스가 기본 포인터를 통해 어떻게 복제 될 수 있습니까?

내가 무엇을 얻을 내가 같은 가 인쇄 "유도"를 참조하는 거라고 무엇
class Base 
{ 
    virtual Base *clone() { return new Base(this); } 
    virtual void ID() { printf("BASE"); 
}; 

class Derived : publc Base 
{ 
    virtual Base *clone() { return new Derived(this); } 
    virtual void ID() { printf("DERIVED"); } 
} 

. 
. 
Derived d; 
Base *bp = &d; 
Base *bp2 = bp->clone(); 

bp2->ID(); 

는 ... "BASE ". 저는 오랫동안 C 프로그래머 였고 C++에 대해 상당히 숙련 된 경험이 있습니다. 그러나이 책으로 어떤 진전을 이루지는 못했습니다 ... 어떤 도움을 주시면 감사하겠습니다.

+0

더 많은 코드를 표시합니다. 특히이 경우 모든 클래스의 모든 생성자가 중요합니다. (어떤 것은 코드에서 유추 할 수 있지만, 모든 사람들이 더 정확한 답을 얻는 데 도움이됩니다 ...) – Macke

+0

흠. 초기 코드는 Base bp = & d였습니다. 이제는 Base * bp = & d;로 변경되었습니다. – Macke

+0

질문과 관련이 없지만 클래스에 가상 소멸자가 필요할 수도 있습니다. –

답변

0

당신은 Base bp = &d;의 클래스 (이 파생-PTR에서 새 기본 혈압을 구성한다.)

대신 Base* bp = &d;을 시도 slicing이야. (즉, 파생 개체를 기본 형식의 포인터를 만들 수 있습니다.) 당신은 "슬라이스"한

+1

OP (현재)에서 OP에 편집 문이 표시되지 않으며 코드가 제안대로 수행 중입니다 (컴파일되지는 않지만). 보고 된 문제가 분명히 슬라이싱 문제의 악취는 아니지만 게시 된 코드는이를 증명하지 못합니다 ... 편집 : 죄송합니다. 편집 오류에 대한 잘못된 게시물을보고 있습니다. 당신 말이 맞아, 마커스. 문제를 일으켜서 미안 해요. –

1

Base bp = &d;

으로 d을, bp 정말 유일한 유형 Base이다 컴파일러, 그래서 어떤 이유 때를 bp->clone()을 호출하면 Base::clone();bp2->ID()BASE으로 인쇄됩니다.

Base& bp = d; 원하는대로 할 수 있습니다.

0

예제가 잘못되어 컴파일되지 않습니다. 특히이 라인 :

Base bp = &d; 

또한 문제의 근본 원인이 될 수있다 (당신은 당신의 객체를 얇게 할 수있다),하지만 작동 코드를 보지 않고 확실히 말할 수 없다.

당신은 또한 당신의 두 클래스는 관련이없는 문제가 (당신은 class Derived : public Base를 작성 찾으시는 것입니까?)

+0

예,이 코드는 컴파일되지 않습니다. 나는이 버그를 게시 한 지 1 분 만에 해결했지만, 여러분은 빠릅니다! 수정 된 질문을 참조하십시오. "조각"이 무엇인지 모르겠으나 찾고 있습니다 ... – wanlessv

+1

@wanlessv - 질문을 게시하기 전에 항상 코드를 컴파일해야합니다. 정확히 무엇을하려고하는지 모르는 상태에서 문제가 무엇인지 항상 알 수는 없습니다. –

3

그 코드는 구문 오류 투성이입니다. 아마도 가장 중요한 것은 Derived가 Base에서 상속받지 않는다는 것입니다. 둘째, 구문 오류 (아마도 단순한 오타)를 제외하고, Base는 분명히 가상 소멸자가 필요합니다. 복제 메소드는 기본 포인터 (Base *)에서 연산자 삭제를 호출 할 수 있어야합니다. 모든 컴파일 오류가 해결되면

class Base 
{ 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const { return new Base(*this); } 
    virtual void ID() const { printf("BASE"); } 
}; 

class Derived: public Base 
{ 
public: 
    // [Edit] Changed return type to Derived* instead of Base*. 
    // Thanks to Matthieu for pointing this out. @see comments below. 
    virtual Derived* clone() const { return new Derived(*this); } 
    virtual void ID() const { printf("DERIVED"); } 
}; 

int main() 
{ 
    Derived d; 
    Base* bp = &d; 

    Base* bp2 = bp->clone(); 
    bp2->ID(); // outputs DERIVED as expected 
    delete bp2; 
} 
+1

나는 모두에게 사과한다. 나는 간단한 예제를 만들어서 실제 코드에 모든 사람들을 묻지 않으려 고 노력했다. 그러나 간단한 버전에서 몇 가지 실수를 저질렀다. 몇 가지 대답을했습니다! 이 시점에서, 나는 나의 진짜 질문에 여전히 관련된 나의 버그가있는 예제에 답하고있는 답이 무엇인지 모른다. – wanlessv

+0

또한 스마트 포인터 (예 : boost :: shared_ptr)를 사용하여 자동으로 bp2를 삭제합니다. –

+0

@Daniel 그래,하지만 OP가 상속과 다형성에 어려움이 있다면, 그가 RAII와 똑똑한 포인터를 이해하기까지는 오래 걸릴 수도 있습니다. – stinky472

7

,이에 결국 :

#include <cstdio> 

class Base 
{ 
    public: 
    Base() {} 
    Base(const Base&) {} 
    virtual Base *clone() { return new Base(*this); } 
    virtual void ID() { printf("BASE"); } 
}; 

class Derived : public Base 
{ 
    public: 
    Derived() {} 
    Derived(const Derived&) {} 
    virtual Base *clone() { return new Derived(*this); } 
    virtual void ID() { printf("DERIVED"); } 
}; 


int main() 
{ 
    Derived d; 
    Base *bp = &d; 
    Base *bp2 = bp->clone(); 

    bp2->ID(); 
} 

을 당신이 찾고있는 무엇을주는 - 산출했다.

+0

감사합니다. 이 예제를 연구하면서, 나는이 문제를 이해하고 있다고 생각한다. – wanlessv

0

어리석은 구문 오타 및 누락 된 코드 이외의 코드는 괜찮아 보입니다.

관련 문제