-3

I tried to override the - operator but I get an error. How to solve the error, and what is it for?

#pragma once

class Resurse
{
protected:
    unsigned int _cantitate;
public:
    Resurse() {}
    Resurse(unsigned int cantitate) :_cantitate(cantitate) {}
    ~Resurse() {}
    Resurse(Resurse&& r)
    {
        _cantitate = r._cantitate;
        r._cantitate = 0;
    }

    virtual Resurse* operator-(Resurse* r)
    {
        Resurse* result=new Resurse(this->_cantitate - r->_cantitate);
        return result;
    }

    unsigned int GetCantitate() { return _cantitate; }
};
#pragma once
#include "Resurse.h"

class Hrana:public Resurse
{
public:
    Hrana() {}
    Hrana(unsigned int cantitate) :Resurse(cantitate) {}
    ~Hrana() {}
    Hrana(Hrana&& h) { _cantitate = h._cantitate; h._cantitate = 0; }

    Resurse* operator-(Resurse* r)
    {
        Resurse* result = new Hrana(this->_cantitate - r->GetCantitate());
        return result;
    }
};

void main()
{
    Resurse* hrana1 = new Hrana(20);
    Resurse* hrana2 = new Hrana(17);
    Resurse* result = hrana1 - hrana2;
    system("pause");
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
ionyy
  • 1
  • 4
  • Which `operator-`? There are two: negation (one parameter) and subtraction (two parameters). The quantity of parameters depends on whether the function is free standing or not. – Thomas Matthews Jan 13 '21 at 18:51
  • yes, minus operator – ionyy Jan 13 '21 at 18:51
  • Does this answer your question? [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – Richard Critten Jan 13 '21 at 18:55
  • thank you, but i tried to overRIDE not overLOAD – ionyy Jan 13 '21 at 19:03
  • this is why I used pointers instead of const & – ionyy Jan 13 '21 at 19:04
  • 2
    No, there's nothing here that requires pointers. This problem is called "useless use of pointers", and it is a common problem for people with Java background that are trying to learn C++. The problem is that C++ is not Java, and C++ objects work in fundamentally different ways. Nothing in the shown code needs to use pointers, and without pointers everything becomes ten times simpler. – Sam Varshavchik Jan 13 '21 at 20:47
  • *"but I get an error"* -- what is the error? – JaMiT Jan 13 '21 at 21:51

1 Answers1

3

Yes, it is possible to overload (not override) operators. However, the problem is, you are not doing it correctly.

You are trying to invoke operator- on Resurce* pointers, not on Resurce objects. Your operator- needs to take a Resurce object by value/reference as input, not by pointer. And return a new Resurce object by value on output, not by pointer. See What are the basic rules and idioms for operator overloading?

And in your main(), you need to dereference the pointers before calling operator-.

Try this:

Resurse operator-(const Resurse &r) const
{
    return Resurse(_cantitate - r._cantitate);
}
int main()
{
    Resurse* hrana1 = new Resurse(20);
    Resurse* hrana2 = new Resurse(17);
    Resurse result = *hrana1 - *hrana2;
    std::system("pause");
    delete hrana2;
    delete hrana1;
}

Or, simply get rid of the pointers altogether, you don't really need them:

int main()
{
    Resurse hrana1(20);
    Resurse hrana2(17);
    Resurse result = hrana1 - hrana2;
    std::system("pause");
}

UPDATE: I just realized that you are trying to implement a polymorphic operator-. That is not going to work, mainly due to object slicing on the return value, but also because you can't overload operators for pointers.

I would suggest using a separate virtual method instead of operator-, eg:

#pragma once
#include <memory>

class Resurse
{
protected:
    unsigned int _cantitate;
public:
    Resurse(unsigned int cantitate = 0) : _cantitate(cantitate) {}
    virtual ~Resurse() {}

    Resurse(const Resurse&) = default;
    Resurse(Resurse&& r)
    {
        _cantitate = r._cantitate;
        r._cantitate = 0;
    }

    virtual std::unique_ptr<Resurse> subtract(const Resurse &r) const
    {
        return std::make_unique<Resurse>(_cantitate - r.GetCantitate());
    }

    unsigned int GetCantitate() const { return _cantitate; }
};
#pragma once
#include "Resurse.h"
#include <memory>
#include <cstdlib>

class Hrana : public Resurse
{
public:
    Hrana(unsigned int cantitate = 0) : Resurse(cantitate) {}

    Hrana(const Hrana& h) = default;
    Hrana(Hrana&& h) : Resurse(std::move(h)) {}

    std::unique_ptr<Resurse> subtract(const Resurse &r) const override
    {
        return std::make_unique<Hrana>(_cantitate - r.GetCantitate());
    }
};

void main()
{
    std::unique_ptr<Resurse> hrana1 = std::make_unique<Hrana>(20);
    std::unique_ptr<Resurse> hrana2 = std::make_unique<Hrana>(17);
    auto result = hrana1->subtract(*hrana2);
    std::system("pause");
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770