I have a “abstract” super class called RealAlgebraicNumber and two inherited classes called IntervalRepresentation and NumericRepresentation. Both IntervalRepresentation and NumericRepresentation have a copy constructor and they work fine.
I use shared_ptr like this:
typedef std::tr1::shared_ptr<RealAlgebraicNumber> RealAlgebraicNumberPtr;
At another part of the programm I want to use the copy constructor for the abstract super class RealAlgeraicNumber:
RealAlgebraicPoint RealAlgebraicPoint::conjoin (const RealAlgebraicNumber& N)
{
vector<RealAlgebraicNumberPtr> v (mNumbers.begin(), mNumbers.end());
v.push_back(RealAlgebraicNumberPtr(new RealAlgebraicNumber(N)));
return RealAlgebraicPoint(v);
}
I did not define a copy constructor for RealAlgebraicNumber at all. I have no idea what it should do. The compiler is fine with the code, but unfortuantly when I test conjoin like this:
vector<RealAlgebraicNumberPtr> v;
v.push_back(RealAlgebraicNumberPtr(new NumericRepresentation(2)));
RealAlgebraicPoint PPP (v);
PPP.print();
PPP = PPP.conjoin (NumericRepresentation(3));
PPP.print();
The output is:
( 2 )( 2 null )
And print was defined like this:
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";
}
I use a loop to call the static-print function and put the representation between the ( ).
I tryed it the way Cat Plus Plus propused: virtual method in RealAlgebraicNumber,
virtual std::tr1::shared_ptr<RealAlgebraicNumber> clone();
implementation in e.g. NumericRepresentation
RealAlgebraicNumberPtr NumericRepresentation::clone()
{
return RealAlgebraicNumberPtr(new NumericRepresentation(*this));
}
And then used it like this in conjoin:
RealAlgebraicPoint RealAlgebraicPoint::conjoin (const RealAlgebraicNumber& N)
{
vector<RealAlgebraicNumberPtr> v (mNumbers.begin(), mNumbers.end());
v.push_back(RealAlgebraicNumberPtr(N.clone()));
return RealAlgebraicPoint(v);
}
Now the compiler complains:
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
I dont get it! Whats wrong?
Edit: Oke its fine! It had something to do with const, and virtual.
Thank you!
Joachim
If you didn’t define a copy ctor, compiler will generate a default one, doing memberwise copy. What you probably want is polymorphic clone, to preserve the type, and call a proper copy ctor. For that, add a new virtual member, e.g.
virtual RealAlgebraicNumber* clone();, and override it in every subclass to doreturn new T(*this);— then yourconjoinwill look like this: