2011-11-04 6 views
2

RealAlgebraicNumber라는 "추상"수퍼 클래스와 IntervalRepresentation 및 NumericRepresentation이라는 두 개의 상속 된 클래스가 있습니다. IntervalRepresentation과 NumericRepresentation에는 모두 복사 생성자가 있으며 제대로 작동합니다."추상"수퍼 클래스의 복사 생성자 사용

이 같은 shared_ptr의를 사용 : 나는 사본을 정의하지 않았다

RealAlgebraicPoint RealAlgebraicPoint::conjoin (const RealAlgebraicNumber& N) 
{ 
    vector<RealAlgebraicNumberPtr> v (mNumbers.begin(), mNumbers.end()); 
    v.push_back(RealAlgebraicNumberPtr(new RealAlgebraicNumber(N))); 
    return RealAlgebraicPoint(v); 
} 

: 나는 추상 슈퍼 클래스 RealAlgeraicNumber의 복사 생성자를 사용할 programm에의 다른 부분에서

typedef std::tr1::shared_ptr<RealAlgebraicNumber> RealAlgebraicNumberPtr; 

RealAlgebraicNumber의 생성자. 나는 그것이 무엇을해야하는지 모른다. 컴파일러는 코드 괜찮지 만, 나는이 같은 결합하다을 테스트 unfortuantly 때

vector<RealAlgebraicNumberPtr> v; 
v.push_back(RealAlgebraicNumberPtr(new NumericRepresentation(2))); 
RealAlgebraicPoint PPP (v); 
PPP.print(); 
PPP = PPP.conjoin (NumericRepresentation(3)); 
PPP.print(); 

출력은 다음과 같습니다

(2) (2 널)

그리고 인쇄는 다음과 같이 정의 하였다 :

void RealAlgebraicNumberFactory::print (const RealAlgebraicNumberPtr& A) 
{ 
    IntervalRepresentationPtr irA = std::tr1::dynamic_pointer_cast<IntervalRepresentation> (A); 
    NumericRepresentationPtr nrA = std::tr1::dynamic_pointer_cast<NumericRepresentation> (A); 
    if (irA != 0) 
     cout << irA->Interval(); 
    else if (nrA != 0) 
     cout << static_cast<numeric>(*nrA); 
    else 
     cout << "null"; 
} 

루프를 사용하여 정적 인쇄 기능을 호출하고() 사이에 표현을 넣습니다. RealAlgebraicNumber 가상 방법, 예를 들어,에서

virtual std::tr1::shared_ptr<RealAlgebraicNumber> clone(); 

구현 :

나는 그것을 고양이 플러스 플러스 propused 방법을 tryed NumericRepresentation

RealAlgebraicNumberPtr NumericRepresentation::clone() 
{ 
    return RealAlgebraicNumberPtr(new NumericRepresentation(*this)); 
} 

그리고이 결합하다이처럼 사용 :

RealAlgebraicPoint RealAlgebraicPoint::conjoin (const RealAlgebraicNumber& N) 
{ 
    vector<RealAlgebraicNumberPtr> v (mNumbers.begin(), mNumbers.end()); 
    v.push_back(RealAlgebraicNumberPtr(N.clone())); 
    return RealAlgebraicPoint(v); 
} 

지금 컴파일러가 불평 :

RealAlgebraicPoint.cpp: In member function 'GiNaC::RealAlgebraicPoint GiNaC::RealAlgebraicPoint::conjoin(const GiNaC::RealAlgebraicNumber&)': 
RealAlgebraicPoint.cpp:66:48: error: passing 'const GiNaC::RealAlgebraicNumber' as 'this' argument of 'virtual std::tr1::shared_ptr<GiNaC::RealAlgebraicNumber> GiNaC::RealAlgebraicNumber::clone()' discards qualifiers 

나는 그것을 얻을 해달라고! 뭐가 문제 야?

편집 : 괜찮아요! 그것은 const, virtual과 관련이 있습니다.

감사합니다.

요아킴

+0

'RealAlgebraicPoint' 무엇입니까? –

+0

이 질문을 단순화 해 줄 수 있습니까? 당신은'class Base;와'class D1 : public Base; class D2 : public Base;', 당신은'Base'에 대한 복사 생성자를 쓰는 방법을 묻고 있습니까? –

+0

동일한 프로그램에서 실행 시간에 실제 수치가 모두 표시됩니다.그렇지 않다면 템플릿으로 된'RealAlgebraicNumberFactory '과 템플릿으로 된 연산 세트를 만들 수 있습니다. 예를 들어'템플릿 T conjoin (const T &)'를 선택한 표현으로 매개 변수화 할 수 있습니다. – Lambdageek

답변

2

당신이 복사의 ctor를 정의하지 않은 경우, 컴파일러는 memberwise 사본을하고, 기본 하나를 생성합니다. 당신이 원하는 것은 다형성 클론 (polymorphic clone), 유형을 보존하는 것, 그리고 적절한 카피 코터 (ctor)를 호출하는 것입니다. 이를 위해 새로운 가상 멤버를 추가하십시오. virtual RealAlgebraicNumber* clone();return new T(*this);을 할 수있는 모든 하위 클래스에서 재정의 - 다음 conjoin는 다음과 같이 표시됩니다

RealAlgebraicPoint RealAlgebraicPoint::conjoin (const RealAlgebraicNumber& N) 
{ 
    vector<RealAlgebraicNumberPtr> v(mNumbers.begin(), mNumbers.end()); 
    v.push_back(RealAlgebraicNumberPtr(N.clone())); 
    return RealAlgebraicPoint(v); 
} 
+0

어떻게 든 동적 객체를 반환하는 것은 잘못된 것처럼 보입니다. 공유 포인터를 다시 돌려주는 것이 가장 좋습니다. –

+0

@KerrekSB : 공유 포인터를 반환 할 수 있습니다. 요점은 올바른 유형으로 호출되어야합니다. 즉 가상 형식이어야합니다. –