Перегрузка операторов в производном классе - PullRequest
10 голосов
/ 15 апреля 2011

Должен ли я переопределить все операторы перегрузки с производным типом, если мне потребуется использовать их в производном классе?

Следующий код прекрасно компилируется:

class Point {

public:

    Point(int X = 0, int Y = 0):x(X), y(Y) {}

    virtual ~Point() {}

    Point operator +(Point &rhs) {
        return Point(x + rhs.x, y + rhs.y);
    }

protected:
    int x, y;
};

class Vector : public Point {

public:

    Vector(int X, int Y) : Point(X, Y) {}

    ~Vector() {}

    Vector operator +(Vector &rhs) {
        return Vector(x + rhs.x, y + rhs.y);
    }
};

int main()
{
    Vector v1(1, 2);
    Vector v2(3, 2);

    Vector v3 = v2 + v1;
}

Но из того, что япрочитал,

C ++ Primer 4th Ed. Section 15.5.3.

Если производный класс хочет сделать все перегруженные версии доступными через его типтогда он должен либо переопределить их всех, либо ни одного из них.

Имеет ли смысл здесь часть цитаты "none of them"?

Ответы [ 3 ]

6 голосов
/ 15 апреля 2011

Это означает, что если у Point было более одного operator+(), и вы переопределили только один из них, тогда только этот будет доступен в производном классе; другие перегрузки будут скрыты. Если вы объявите no operator+() в производном классе, тогда будут доступны все родительские классы; если вы объявляете any в производном классе, тогда доступны none из родительских классов.

Имеет смысл? Это хорошо: родитель объявляет один, а вы переопределяете этот. Нет проблем. Однако если родитель объявил два, тогда ваш дочерний класс, который объявляет только один, будет иметь доступ только к этому.

6 голосов
/ 15 апреля 2011

Перегрузка операторов в производном классе от IBM.

Функция-член с именем f в классе A скроет все остальные члены с именем f в базовые классы А, независимо от возвращаемые типы или аргументы. следующий пример демонстрирует это:

struct A {
  void f() { }
};

struct B : A {
  void f(int) { }
};

int main() {
  B obj_B;
  obj_B.f(3);
//  obj_B.f();
}

Компилятор не позволит вызов функции obj_B.f (), потому что объявление void B :: f (int) имеет скрытый A :: f ().

Перегрузить, а не спрятать функция базового класса А в производный класс B, вы вводите имя функции в сферу B с объявлением об использовании. Следующий пример такой же, как предыдущий пример за исключением использования объявление с использованием A :: f:

struct A {
  void f() { }
};

struct B : A {
  using A::f;
  void f(int) { }
};

int main() {
  B obj_B;
  obj_B.f(3);
  obj_B.f();
}

Так что, если вы не перегрузите их все, будут использоваться только перегруженные функции.

2 голосов
/ 15 апреля 2011

В C ++ нет перегрузки между областями действия. Производные области классов не являются исключением из этого общего правила.

Нет разрешения перегрузки между производным и базовым классом. Пример:

class B
{
    public:
    int func1(int i)
    {
        cout<<"B::func1()";
        return i+1;
    }
};



class D : public B
{
    public:
    double func1(double d)
    {
        cout<<"D::func1()";
        return d+1.3;
    }
};

int main ()
{
    D *pd = new D;

    cout << pd->func1(2)  <<endl;
    cout << pd->func1(2.3)<<endl;

    return 0;
}

Вывод:

D::func1()3.3
D::func1()3.6

Это же правило применяется и к функциям-членам оператора, ведь они тоже являются функциями-членами!

Итак, в вашем примере кода, если Point имел более одного operator+(), и вы переопределили один и тот же оператор в производном классе, тогда только этот оператор производного класса будет доступен для объектов производного класса, потому что эта версия функции hides другие версии базового класса operator+().
Если вы не переопределите operator+() в производном классе, то ни одна из версий родительского класса operator+() не будет скрыта и, следовательно, доступна через объекты класса Derived.

Отсюда и утверждение:
If a derived class wants to make all the overloaded versions available through its type, then it must either redefine all of them or none of them.

Также, пожалуйста, обратите внимание, что overloading, overriding и function hiding - это три термина, которые свободно неправильно используются иногда взаимозаменяемо, но все они имеют разные значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...