【问题标题】:Overloading pure virtual operators重载纯虚拟运算符
【发布时间】:2019-10-21 21:54:19
【问题描述】:

我有抽象类 Number 和 4 个纯虚拟运算符 (+,-,/,*)。我想创建两个派生类IntegerReal 并在那里覆盖这些运算符。我没有正确理解如何声明运营商。我在网上没有找到任何与我的情况相似的例子。

我的问题是: 在抽象基类Number 中,我的运算符必须返回引用Number& 或指针Number*,因为我不能返回抽象类本身。但是我应该传递什么作为参数? Number&Number* 也是,但我需要在课堂上存储数字,我的基类中是否应该有类似 void* num 的东西? 让我们想象一下,我有

class Number {
    ...
    virtual Number& operator+(const Number&) = 0;
};

我应该如何在派生类Integer中覆盖这个运算符?

【问题讨论】:

  • 假设你有那个类层次结构,你能举个例子你会如何使用它吗?不清楚你到底想得到什么。
  • @Evg hm,类似于简单的自定义 int 类。
  • 不确定您的设计是否正确...您需要能够以这种方式添加 Integers 和 Reals - 但除非您有一些共同点数字表示,您需要了解类型...另一方面,如果您有这样的通用表示,那么为什么不在 Number 基类中使用呢?
  • " 我真的不需要 atm 来添加 real+int only real+real, int+int" 那么为什么首先要关心虚拟方法或继承呢?您不需要 IntegerReal 从基类继承以启用 Integer + IntegerReal + Real

标签: c++ operator-overloading abstract-class derived-class pure-virtual


【解决方案1】:

我知道,但是我的导师坚持要像在抽象类中练习那样覆盖纯虚拟运算符,但我真的不明白。

嗯,你可以从中了解到两件事:

  1. 虚函数一般是如何工作的(自定义运算符只不过是普通函数,只是调用语法不同)。
  2. 虚拟函数并不是解决任何问题的圣杯。

问题在于 IntegerReal 类很可能具有不同的内部表示 - 因此您将无法进行加法/乘法/...在不知道您作为第二个收到的具体类型的情况下操作数。此外,还不清楚混合操作数类型的返回类型应该是什么。

我真的不需要atm添加real+int只real+real,int+int

好吧,我们可以抓住这个:

class Number
{
public:
    virtual ~Number() { } // in any case, a virtual base class should have a virtual destructor!

    // fine so far:
    virtual Number& operator+(Number const&) const = 0;
    // we are not going to change the          ^
    // own instance, so we'd rather have this operator const
    // (in contrast to operator+=)
};

class Integer : public Number
{
public:
    Integer& operator+(Number const& other) const override
    // ^ co-variant return type, so that's fine
    {
        // at very first, we make sure that we actually received
        // an instance of type Integer
        auto o = dynamic_cast<Integer const*>(&other);
        if(!o)
            // if not, throwing an exception is a good candidate
            // for error handling...
            throw std::invalid_argument("argument must be of type Integer");

        // now as we know it IS an Integer:
        return Integer(this->value + o->value); // or whatever...
        // OOPS - the returned object gets lost when the function is left...
    }
};

如果您也希望能够添加Reals,那么您将有另一种类型转换。假设Integer + Real 的结果是Real,那么您必须将返回类型改回Number

然而,其中还存在一个很大的问题:函数一离开,返回的对象就被销毁了,所以返回的引用是悬空的。

我们必须通过某种方式解决这个问题。不过,引用并不合适,因此我们可能会选择智能指针:

class Number
{
    virtual std::unique_ptr<Number> operator+(Number const&) const = 0;
};

class Integer : public Number
{
    std::unique_ptr<Number> operator+(Number const& other) const override
    //                 ^
    // unfortunately, now, as ordinary struct, no co-variance possible any more
    {
        return std::make_unique<Integer>(this->value + o->value);
    }
};

这个问题再次说明了实际选择的方法是多么不合适......

【讨论】:

  • 你的陈述的温和版本是“虚拟函数不是解决所有问题的圣杯。”虽然我完全同意你写的:)
  • 你在这里返回一个悬空引用。一种可能的解决方案是返回std::unique_ptr&lt;Number&gt;
  • @Evg 该死的,当然。完全不使用返回引用的操作员......再次证明强加的概念是多么糟糕。
  • 上帝保佑你们,小伙子们。
  • @Evg 绝对。今天好像没注意 :(
猜你喜欢
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
  • 2012-12-02
  • 2021-11-12
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多