2013-02-27 1 views
1
으로 다음 코드는 컴파일 오류를주고있다

: 는 " 'Cloneable을 *'로 변환 할 수없는 'AClass *'"내 지식을 당로서,이 거래 라인 1 에 컴파일 시간과 실행 시간 다형성에 대한 개념을 가지고 있습니다. 그러나 이것에 대해서는 구체적인 이유가 없습니다. 기본적으로다형성 : 컴파일시 상기 code.Need 오류에 대한 설명

struct Cloneable 
{ 
virtual Cloneable* clone() 
    { 
    cout << "Cloneable"; 
    return new Cloneable; 
    } 

    virtual ~Cloneable() {} 
}; 


struct AClass : public Cloneable 
{ 
    virtual AClass* clone() 
    { 
    cout << "AClass"; 
    return new AClass; 
    } 
}; 

int main() 
{ 
Cloneable* s1 = new AClass; 
AClass* s2 = s1->clone();  //Line 1 
return 0; 
} 

답변

1

, 당신은 당신의 기본 클래스 포인터에 새 AClass *을 저장하면, 항상 안전하지 않을 수있는 AClass *로 다운 캐스트해야 할 것 Cloneable를 *이 될 것입니다 복제를 호출 한 결과 . 따라서 컴파일러는 a를 원할 것입니다 dynamic_cast()

+0

@muhmud ...이 코드는 내가 static_cast를 (사용하는 경우) 잘 작동합니다 (파생 클래스 포인터 유형으로 기본 클래스 포인터 타입 캐스팅) .Modifying 라인 1과 : AClass * S2 = static_cast (S1 -> clone()); 내가 정말로 알고 싶은 것은 컴파일러가이 코드를 해석하는 방법입니다. – user2100866

+0

@ user2100866 - 이걸 봐야합니다 - http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast. 'dynamic_cast()'는 정의되지 않은 동작을 방지 할 수있는 다운 캐스팅 중에 런타임 검사를 수행합니다. – muhmud

1

캐스트로 "작업"할 수는 있지만 실제로하는 일은 매우 위험합니다. 동적으로 할당 된 두 개의 개체를 삭제하는 것을 잊었습니다. 동적 메모리 할당을 숨기는 것도 좋은 생각이 아닙니다. 특히 어디에도 삭제하지 않는 것이 좋습니다. 그냥 std :: unique_ptr 또는 std :: shared_ptr를 사용하는 것이 훨씬 쉬우 며 스택에 객체를 할당하기 만하면됩니다.

편집 : 첫 번째 직선 대답을 포기하지 않을에 대한 나의 사과 : 당신은 Cloneable 포인터에 clone()를 호출

AClass* s2 = dynamic_cast<AClass*>(s1->clone()); 
+0

작업을하기 전에 코드 흐름을 알고 싶습니다. – user2100866

1

. 이 방법은 Cloneable*를 반환, 그래서 당신이 필요합니다

Cloneable* s2 = s1->clone(); 

이는 AClass를 인스턴스화합니다. 이것은이 복제 관용구를 사용하는 표준 방법입니다. 다형성을 올바르게 사용하는 경우 Cloneable* 또는 AClass* 일지는 중요하지 않습니다. 따라서 보통 Cloneable*AClass::clone()에서 반환합니다. 물론 스마트 포인터를 반환하는 것이 좋습니다.

struct AClass 
{ 
    virtual std::unique_ptr<Cloneable> clone(); 
}; 

struct AClass : public Cloneable 
{ 
    virtual std::unique_ptr<Cloneable> clone(); 
};