我可以用C ++覆盖运算符吗?

时间:2014-09-26 19:51:15

标签: c++ oop c++11

我知道我们可以为一个类重载运算符。但我的问题是我是否可以覆盖运营商?

让我们考虑一下我有一个基类和派生类,是否可以覆盖派生类中基类中的运算符定义(重载)(与函数重写一样)?

3 个答案:

答案 0 :(得分:11)

通过提供"封面&#34>,您可以达到预期的效果。基类中的虚函数,并从基类中的运算符实现中调用它:

struct Base {
    Base operator+(const Base& other) {
        return add(other);
    }
protected:
    virtual Base add(const Base& other) {
        cout << "Adding in Base's code." << endl;
        return Base();
    }
};

struct Derived : public Base {
protected:
    virtual Base add(const Base& other) {
        cout << "Adding in Derived's code." << endl;
        return Derived();
    }
};

int main() {
    Base b1;
    Base b2;
    Derived d1;
    Derived d2;
    Base res;
    res = b1+b2; // Prints "Adding in Base's code."
    res = b1+d2; // Prints "Adding in Base's code."
    res = d1+b2; // Prints "Adding in Derived's code."
    res = d1+d2; // Prints "Adding in Derived's code."
    return 0;
}

Demo.

答案 1 :(得分:10)

重载运算符只是一个函数,因此它可以是虚拟的,也可以被覆盖。

但它很少是一个好主意。

考虑一个重写的复制赋值运算符,在某些派生类中检查要分配的值是否与分配给的对象兼容。实际上它已经用动态类型检查取代了静态类型检查,这涉及大量繁琐的测试,只有统计的正确性。


ungoodness的例子:

#include <assert.h>
#include <iostream>
#include <string>
using namespace std;

struct Person
{
    string name;

    virtual
    auto operator=( Person const& other )
        -> Person&
    { name = other.name; return *this; }

    Person( string const& _name ): name( _name ) {}
};

struct Employee: Person
{
    int     id;

    auto operator=( Person const& other )
        -> Person&
        override
    {
        auto& other_as_employee = dynamic_cast<Employee const&>( other );

        Person::operator=( other );
        id =  other_as_employee.id;
        return *this;
    }

    auto operator=( Employee const& other )
        -> Employee&
    {
        return static_cast<Employee&>(
            operator=( static_cast<Person const&>( other ) )
            );
    }

    Employee( string const& _name, int const _id )
        : Person( _name )
        , id( _id )
    {}
};

void foo( Person& someone )
{
    someone = Person( "Maria" );        // Fails, probably unexpectedly.
}

auto main() -> int
{
    Person&& someone = Employee( "John", 12345 );
    foo( someone );
}

答案 2 :(得分:1)

我想补充一点:在我个人对内置类型的某些操作符的默认行为感到沮丧之后,我想知道是否有可能以简单易读的方式覆盖这些操作符。答案是my Polyop project,这正是如此。

那么,你可以覆盖C ++运算符的默认行为吗?是的,只是以操作符调用看起来相同的方式包装它们,但它实际上调用的是一个完全不同的运算符使用您定义的属性和行为。

//Redefine the behavior of the int vs int equality operator
auto operator==(void(int,int) , pop::default_context )
{
    return [](int lhs , int rhs )
    {
        return lhs * 2 == rhs;
    };
}

using pop::triggers::_;

int main()
{
    bool equal = _(4) == 2; //Returns true, since its the behavior we defined above
}

所有人都没有表现出色。