Итак, у меня есть вопрос, касающийся вывода следующего кода (который 111222223)
#include <iostream>
struct C {
virtual int eq(const C& other) const { return 1; }
};
struct SC : C {
virtual int eq(const C& other) const { return 2; }
virtual int eq(const SC& other) const { return 3; }
};
void go(const C& c, const C& c1, const SC& sc) {
using namespace std;
cout << c.eq(c) << endl;
cout << c.eq(c1) << endl;
cout << c.eq(sc) << endl;
cout << c1.eq(c) << endl;
cout << c1.eq(c1) << endl;
cout << c1.eq(sc) << endl;
cout << sc.eq(c) << endl;
cout << sc.eq(c1) << endl;
cout << sc.eq(sc) << endl;
}
int main(int argc, const char* argv[]) {
go(C(), SC(), SC());
return 0;
}
Итак, я понимаю, что я использую оператор точки со ссылкой, которая будет динамически связывать правильный виртуальный метод, основанный на типе вызывающей стороны во время выполнения (потребуется -> с указателями, но ОК для динамического анализа здесь). Чего я не понимаю, так это того, почему вторая-последняя строка cout печатает «2», а не «3». Это потому, что сигнатура метода является статической, поэтому метод выбирается на основе статической сигнатуры в правильном производном типе SC? Спасибо за помощь в продвижении!
В C ++ не поддерживается множественная диспетчеризация, только для объекта, для которого вызывается функция (динамическая диспетчеризация применяется только к this
указатель). В выражении:
sc.eq(c1);
компилятор отправит динамический тип sc
, но будет использовать статический тип c1
Это связано с правилами разрешения функций.
В этом призыве:
sc.eq(c1);
Легко вызывать только одну функцию, если тип c1 struct C
с eq
динамически перегружен.
Но в вызове
sc.eq(sc);
у вас есть два возможных eq
функции для вызова. Первый объявлен в struct C
с динамически перегруженным eq
а второй объявлен в struct SC
, однажды sc
имеет тип struct SC
последний метод более жизнеспособен, чем первый.
Вот почему вы получаете 3
в результате.