Ковариантные типы возврата и отправка

Меня смущает эта простая программа:

#include <iostream>

using namespace std;

struct Base {
  virtual ~Base() {}
  virtual Base* concrete() { cout << "concrete returning base - "; return this;}
  void stat() { cout << "I'm a BASE\n";}
};

struct Derived: Base {
  Derived* concrete() override { cout << "concrete returning derived - "; return this;}
  void stat() { cout << "I'm a DERIVED\n";}
};


int main() {
  Base * bd = new Derived;
  bd->stat();  // prints: "I'm a BASE"
  bd->concrete()->stat(); //prints: "concrete returning derived - I'm a BASE"

  delete bd;
  return 0;
}

Почему последняя строка не печатает concrete returning derived - I'm a DERIVED? Что тут происходит?


person DarioP    schedule 16.06.2014    source источник


Ответы (1)


Вы неправильно понимаете полезность ковариантного возвращаемого типа... он срабатывает, когда вызывающий контекст знает, что имеет дело с объектом типа Derived:

Derived d;
d->concrete()->stat();

В вашем случае concrete вызывается для Base*, поэтому, хотя он отправляется полиморфно и возвращает Derived*, этот указатель обрабатывается как Base* в контексте вызова, и именно статический тип Base* определяет статическую отправку в stat().

person Tony Delroy    schedule 16.06.2014