2

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 DoubleClass;

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);
};
2
  • I assume IntClass::operator+() was meant to be public, right? Commented Jan 10, 2011 at 20:17
  • Was something wrong with the explanation you got on your earlier question? Commented Jan 10, 2011 at 20:21

2 Answers 2

6

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 +.

Sign up to request clarification or add additional context in comments.

5 Comments

"cannot be done" -- them's fightin' words. It requires a redesign, but is most certainly possible.
@Ben: … cannot be done using that interface, without breaking basic assumptions of C++ that would make using the API infernal.
@Ben: Scott Meyers, Effective C++, Item 21 (3rd ed)/23 (2nd ed.): "Don't try to return a reference when you must return an object". More than 4 pages with an excellent analysis why operator+ must return an object (rather than a reference).
@sbi: So return an object. By value. Polymorphism requires that there's a pointer or reference somewhere around, not that the return value is a pointer or reference. See my answer.
@Ben - you can't. What would you return? If you can convert any of the derivatives of Number directly into a Number value then those derivatives are doing nothing. If they ARE doing something then converting any one of them to a Number value is going to lose any interesting data that makes them derivatives.
2

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;
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.