是否可以覆盖 C++ 中的运算符?如果答案是肯定的,范围是什么?

问题描述

我尝试覆盖 - 运算符,但出现错误错误如何解决,是为了什么?

#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");
}

解决方法

是的,可以重载(而不是覆盖)运算符。但是,问题是,您没有正确操作。

您试图在 operator- 指针上调用 Resurce*,而不是在 Resurce 对象上。您的 operator- 需要将 Resurce 对象通过值/引用作为输入,而不是通过指针。并在输出时按值返回一个新的 Resurce 对象,而不是按指针。见What are the basic rules and idioms for operator overloading?

在您的 main() 中,您需要在调用 operator- 之前取消引用指针。

试试这个:

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

或者,干脆完全摆脱指针,你并不真正需要它们:

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

更新:我刚刚意识到您正在尝试实现多态 operator-。这是行不通的,主要是因为返回值上有 object slicing,还因为您不能为指针重载运算符。

我建议使用单独的虚拟方法而不是 operator-,例如:

#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");
}