polymorphism in C++
I am trying to implement the next 2 functions
Number& DoubleClass::operator+( Number& x);
Number& IntClass::operator+(Number& x);
I am not sure how to do it..(their unidirectionality is explained below):
class IntClass;
class Doubl开发者_StackOverflow中文版eClass;
class Number {
//return a Number object that's the results of x+this, when x is either
//IntClass or DoubleClass
virtual Number& operator+(Number& x) = 0;
};
class IntClass : public Number {
private:
int my_number;
//return a Number object that's the result of x+this.
//The actual class of the returned object depends on x.
//If x is IntClass, then the result if IntClass.
//If x is DoubleClass, then the results is DoubleClass.
public:
Number& operator+(Number& x);
};
class DoubleClass : public Number {
private:
double my_number;
public:
//return a DoubleClass object that's the result of x+this.
//This should work if x is either IntClass or DoubleClass
Number& operator+( Number& x);
};
You can’t.
The problem is that operator +
returns a new object and you cannot in good conscience return a reference – this would necessarily either be a dangling reference or a reference to unmanaged heap memory that you would have to free manually.
In summary, this cannot be done using the operator +
.
You need to separate polymorphism from the type being returned. You can do that with encapsulation.
For example:
class Number
{
class NumberImpl
{
public:
virtual ~NumberImpl(){}
virtual NumberImpl* add(Number x) const = 0;
};
class IntClass;
class DoubleClass;
auto_ptr<NumberImpl> pimpl;
Number(NumberImpl* p) : pimpl(p) {}
//return a Number object that's the results of x+this, when x is either
//IntClass or DoubleClass
public:
Number operator+( const Number& x ) const { return Number(pimpl->add(x)); }
};
class Number::IntImpl : public Number::NumberImpl
{
private:
int my_number;
public:
//return a Number object that's the result of x+this.
//The actual class of the returned object depends on x.
//If x is IntImpl, then the result is new IntImpl.
//If x is DoubleImpl, then the results is new DoubleImpl.
virtual NumberImpl* add(Number& x) const;
};
class Number::DoubleImpl : public Number::NumberImpl
{
private:
double my_number;
public:
//return a new DoubleImpl object that's the result of x+this.
//This should work if x is either IntImplor DoubleImpl
virtual NumberImpl* add(Number& x) const;
};
精彩评论