2011-01-10 12 views
1

Ich versuche, die nächsten 2 FunktionenPolymorphismus in C++

Number& DoubleClass::operator+(Number& x); 
Number& IntClass::operator+(Number& x); 

Ich bin nicht sicher zu implementieren, wie es geht .. (ihre Innigkeit erklärt weiter unten):

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); 
}; 
+0

Ich gehe davon aus 'IntClass :: operator +()' war zu sein 'public', nicht wahr? – chrisaycock

+0

War etwas falsch mit der Erklärung, die Sie bekommen haben [Ihre frühere Frage] (http://stackoverflow.com/questions/4633767/how-to-return-a-reference-in-c)? –

Antwort

2

Sie müssen den Polymorphismus vom zurückgegebenen Typ trennen. Sie können das mit Kapselung machen.

Zum Beispiel:

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

Sie können‘ t.

Das Problem ist, dass operator + gibt ein neues Objekt und Sie können einen Verweis nicht mit gutem Gewissen zurückgeben - dies würde entweder unbedingt ein baumelnden Verweis oder ein Verweis auf nicht verwalteten Heap-Speicher, die Sie würde manuell befreien muß.

Zusammenfassend kann dies nicht mit der operator + durchgeführt werden.

+0

"Kann nicht gemacht werden" - sie kämpfen miteinander. Es erfordert ein Redesign, ist aber durchaus möglich. –

+4

@Ben: ... kann nicht mit dieser Schnittstelle durchgeführt werden, ohne grundlegende Annahmen von C++ zu brechen, die die API infernal machen würde. –

+0

@Ben: Scott Meyers, Effektive C++ _, Artikel 21 (3. Ausgabe)/23 (2. Ausgabe): "Versuchen Sie nicht, eine Referenz zurückzugeben, wenn Sie ein Objekt zurückgeben müssen". Mehr als 4 Seiten mit einer exzellenten Analyse, warum 'operator +' _must_ ein Objekt (anstatt einer Referenz) zurückgeben muss. – sbi