如何覆盖多态运算符

时间:2019-02-18 11:14:12

标签: c++ polymorphism operator-overloading operators

有人可以向我解释我在做什么错吗?

struct X {
    int x{};

    explicit X(int x) : x(x) {}

    virtual X &operator++() = 0;
};

struct OK : X {
    int ok{};

    explicit OK(int ok) : X(ok), ok(ok) {}

    X &operator++() override {
        ok += 10;
        return *this;
    }
};

struct MU : X {
    int mu{};

    explicit MU(int mu) : X(mu), mu(mu) {}

    X &operator++() override {
        mu *= 5;
        return *this;
    }
};

int main() {
    X *x_base = new OK(0);
    ++x_base;
    std::cout << x_base->x;
    return 1;
};

我要做的就是将多态性的概念用于运算符,特别是operator ++。我想要这样的结果:


  

Base * base = new Derivate();

     

++ base <--- ++应该从Derivate类中调用


  

Base * base2 = ned Derivate_2();

     

++ base <--- ++应该从Derivate_2类中调用


更新:

当前解决我的问题的方法是使用我已经知道的 ++(* base)

但是还有什么其他方法可以代替 ++(* base)来实现 ++ base 吗?


感谢您的帮助:)

3 个答案:

答案 0 :(得分:9)

在这两行中,

X *x_base = new OK(0);
++x_base;

您创建一个指向新实例的 pointer ,然后增加该指针而不是pointee。永远不会调用类层次结构的增量运算符,而是为指针调用内置的增量运算符。您可以先取消对指针的引用来解决此问题:

++*x_base; // or ++(*x_base), might be more readable

您还可以使用引用而不是指针,这允许增量语法而无需取消对指针的引用,例如

OK ok(0);
X& x_base = ok;

++x_base; // now, x_base is a reference, no need to dereference it

请注意,调用的操作符重载的实现不会更改X::x的值。递增之后的std::cout << x_base->x;表明您期望该值不为零。

答案 1 :(得分:3)

要解决第二个问题,您需要为指针类编写包装器。像

class XPtr
{
public:
    XPtr(X* p) : ptr(p) {}
    X* operator->() { return ptr; }
    X& operator*() { return *ptr; }
    XPtr& operator++() { ++*ptr; return *this; }
private:
    X* ptr;
};

int main() {
    XPtr x_base = new OK(0);
    ++x_base;
    std::cout << x_base->x;
    return 1;
};

答案 2 :(得分:0)

不要这样做。

首先,使用++来表示+= 10*= 5可能会让您被解雇。

算术运算符用于实际上表现得像数学对象或指针/迭代器的事物。从这种意义上讲,几乎没有任何理由让此类对象表现出任何运行时多态性。

++可以在指针上工作后,最好不要迭代struct MUstruct OK的任何数组。

运行时多态性是不得已的工具。除非您真正需要它,否则不要理会它。

最好的解决方案是摆脱虚拟和继承层次结构以及覆盖。如果失败,则应仅命名函数而不是使用运算符。

这不是一个好主意。