Как и в случае с членом закрытой функции, вызываемым вне класса, можно написать следующий код:
#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
не гарантирует, что вы эффективно реализуете специализацию. Вам нужно учитывать больше свойств кода, чтобы быть уверенным, что у вас «правильная» специализация.
Я ошибаюсь ? Кто-нибудь может дать мне обоснование для этого? Мне нужен хороший семантический аргумент, я имею в виду, по крайней мере, что-то гораздо более сложное, чем аргументы Страуструпа, например, «С++ старается не ограничивать вас, вы можете использовать его, если хотите, и не можете, если не хотите». Я думаю, что язык должен быть основан на разумной модели, а не на огромном списке возможных уловок.
B
существует, то не нужно ничего в ней защищать. - person Jean-Baptiste Yunès   schedule 23.01.2015