2

See the following code:

#include<iostream>

using namespace std;


class ex
{
    int i;
public:
    ex(int x){i=x;}
    void operator-()
    {
        i=-i;
    }
    int geti(){return i;}
};

class derived:public ex
{
    int j;
public:
    derived(int x,int y):ex(x){j=y;}
    void operator-()
    {
     j=-j;
    }
    int getj(){return j;}
};


int main()
{
    derived ob(1,2);
    -ob;
    cout<<ob.geti();
    cout<<"\n"<<ob.getj();
}

output:

1
-2
Process returned 0 (0x0)   execution time : 0.901 s
Press any key to continue.

I define the - operator in both the base and derived classes, but -ob; calls only the operator of the derived class. So how to also change the i field to -i (calling the operator in the base class).

Do I need any explicit function to achieve this?

JaMiT
  • 14,422
  • 4
  • 15
  • 31
srilakshmikanthanp
  • 2,231
  • 1
  • 8
  • 25
  • 2
    `static_cast(this)->operator-();` would do it, but that is not going to go well if somebody subtracts two (references to) `ex` objects. Also note that `operator-` shouldn't return `void` but a negated _copy_. Recommended reading: https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading – Max Langhof Dec 11 '19 at 12:07
  • Does this answer your question? [(C++) Invoking base operator from derived class operator](https://stackoverflow.com/questions/21962842/c-invoking-base-operator-from-derived-class-operator) – JaMiT Dec 11 '19 at 12:29

2 Answers2

5

It seems you mean

void operator-()
{
    ex::operator -();
    j=-j;
}

In any case it would be better to declare the operators like for example

ex & operator-()
{
    i = -i;

    return *this;
}

and

derived & operator-()
{
    ex::operator -();

    j = -j;

    return *this;
}

You could also make the operator virtual. For example

#include<iostream>

using namespace std;


class ex
{
    int i;
public:
    virtual ~ex() = default;

    ex(int x){i=x;}
    virtual ex & operator-()
    {
        i = -i;

        return *this;
    }

    int geti(){return i;}
};

class derived:public ex
{
    int j;
public:
    derived(int x,int y):ex(x){j=y;}
    derived & operator-() override
    {
        ex::operator -();

        j = -j;

        return *this;
    }
    int getj(){return j;}
};


int main()
{
    derived ob(1,2);

    ex &r = ob;

    -r;

    cout<<ob.geti();
    cout<<"\n"<<ob.getj();
}    
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • The unary `operator-()` generally returns a negated copy, by value of its operand (e.g. following the "behave like `int`" guideline when overloading operators). So the expression `-ob` doesn't generally change the object `ob`, and creates a distinct object. – Peter Dec 11 '19 at 12:53
  • @Peter I agree but the author of the question wants to change the object "in place".:) – Vlad from Moscow Dec 11 '19 at 12:57
1

Your derived class could be declared like this:

class derived:public ex
{
    int j;
public:
    derived(int x,int y):ex(x){j=y;}
    void operator-()
    {
        j=-j;
        ex::operator-();
    }
    int getj(){return j;}
};
  • 1
    I am always a bit picky about "should" when "can" would be sufficient. For example also for `j` one should use the initializer list instead of assignment in constructors body – 463035818_is_not_an_ai Dec 11 '19 at 12:26