перегрузка виртуального оператора -> () - PullRequest
9 голосов
/ 05 июня 2011

Это просто экспериментальный код.

struct B
{
  virtual B* operator -> () { return this; }
  void foo () {} // edit: intentionally NOT virtual
};

struct D : B
{
  virtual D* operator -> () { return this; }
  void foo () {}
};

int main ()
{
  B &pB = *new D;
  pB->foo();  // calls B::foo() !
}

Я знаю, что operator должен вызываться с использованием объекта или ссылки;таким образом, в вышеприведенном случае ссылка pB все еще решительна на объект B?Хотя это не будет практично, но для любопытства, есть ли способ вызвать от D::operator -> до pB?

Ответы [ 4 ]

8 голосов
/ 05 июня 2011

Я думаю, что вызывает D::operator->, но возвращаемое значение рассматривается как B*, поэтому вызывается B::foo().

Это артефакткак ведут себя ковариантные типы возврата .

2 голосов
/ 05 июня 2011

pB относится к типу B&.Следовательно, любой вызванный метод (например, operator->) получит подпись в B, поэтому pB.operator->() вернет B*.Конечно, поскольку он виртуальный, используется фактическая реализация в D.Важно то, что тип возвращаемого значения определяется типом переменной pB.

Итак, наш operator-> вернул B*, и, следовательно, вызов foo() продолжается, как и для любого другого B*.

1 голос
/ 05 июня 2011

Виртуальные функции-члены вызываются в соответствии с динамическим типом объекта, используемого в вызове.Не виртуальные функции-члены вызываются в соответствии с типом static объекта, используемого в вызове.

Функция foo не является виртуальной.Это означает, что он всегда вызывается в соответствии с статическим типом объекта.Статический тип в этом случае - B (поскольку объявленный тип результата B::operator -> равен B *), поэтому вызывается B::foo.

1 голос
/ 05 июня 2011

Неважно, какой оператор он вызывает (который в данном случае, вероятно, D::operator->), важен this. В этом случае указатель this имеет тип B*, поэтому вызов foo разыменовывается до B::foo. Если бы это было virtual - это работало бы правильно, но вы намеренно не сделали это virtual ...

...