Открытый виртуальный метод переопределен как закрытый. Обобщение / специализация / нарушение принципов Лискова?

Как в Закрытый член функции вызван вне класса, можно написать следующий код:

#include <iostream>

class A {
public:
virtual void f() { std::cout << "A::f()"; }
};

class B : public A {
private:
void f() override { std::cout << "B::f()"; }
};

void g(A &g) { g.f(); }

int main() {
A a;
g(a);
a.f();
B b;
g(b);
b.f(); // compilation failure
}

Конечно, компилятор отказывается компилировать последнюю строку, потому что статический анализ кода показывает, что B::f() определяется, но личное.

Что меня серьезно беспокоит, так это отношение к концептуальному обобщению / специализации. Обычно считается, что вы должны иметь возможность манипулировать экземпляром подтипа, по крайней мере, так же, как вы управляете экземпляром супертипа.

Это основа Принцип подстановки Лискова. В данном примере это соблюдается, когда g() вызывается либо с аргументом типа A или один из типа B, Но последняя строка не принимается, и кажется, что в таком случае принцип замещения каким-то образом нарушается (рассмотрим вызов по имени, как в макроопределении #define h(x) (x.f())).

Даже если можно считать, что принцип Лискова не нарушен (макросы не являются реальной частью языка, так что все в порядке), тот факт, что последняя строка дает ошибку времени компиляции, по крайней мере, означает, что объекты типа B нельзя манипулировать как Aможет быть. Чтобы B это не специализация A даже если вывод public,

Таким образом, в C ++, используя public деривация не гарантирует, что вы эффективно реализуете специализацию. Вам нужно учитывать больше свойств кода, чтобы быть уверенным, что у вас есть «правильная» специализация.

Я ошибся ? Может ли кто-нибудь дать мне оправдание? Мне нужен хороший семантический аргумент, я имею в виду, по крайней мере, что-то гораздо более сложное, чем у Страуструпа, например: «C ++ старается не ограничивать вас, вы можете использовать его, если хотите, и нет, если не хотите». Я думаю, что язык должен основываться на разумной модели, а не на огромном списке возможных трюков.

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]