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

Ven*_*esh 10 c++ oop c++11

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

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

das*_*ght 11

您可以通过在基类中提供"覆盖"虚函数来实现所需的效果,并从基类中的运算符实现中调用它:

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;
}
Run Code Online (Sandbox Code Playgroud)

演示.

  • [非虚拟界面](http://www.gotw.ca/publications/mill18.htm)也是一个非常好的习惯用法!(这里甚至是必要的) (4认同)

Che*_*Alf 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 );
}
Run Code Online (Sandbox Code Playgroud)