公共虚拟方法被重写为私有。泛化/专业化/ Liskov原则违规?

时间:2015-01-22 21:36:20

标签: c++ oop solid-principles design-principles

Private function member called outside of class一样,可以编写以下代码:

#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()已定义但是私有。

严重困扰我的是与概念概括/专业化的关系。通常认为您必须能够操纵子类型的实例,至少与操作超类型实例的方式相同。

这是Liskov's substitution principle的基础。在给定的示例中,当使用类型为g()的参数或类型为A的参数调用B时,这会得到尊重。但最后一行不被接受,似乎在这种情况下,取代原则以某种方式被违反(考虑在宏定义#define h(x) (x.f())中按名称调用)。

即使有人可能认为Liskov的原则没有被违反(宏不是语言的真正部分,那么好),最后一行给出编译时错误的事实,至少意味着类型为{的对象{1}}无法被操纵,因为B可以。因此即使推导为AB也不是A的特化。

因此,在C ++中,使用public派生并不能保证您有效地实现了专门化。您需要考虑代码的更多属性,以确保您具有“正确”的专业化。

我错了吗?有人能给我一个理由吗?我想要一个很好的语义论证,我的意思是至少比Stroustrup更精细的东西比如'C ++试图不约束你,如果你想要你可以自由使用它而不是你不想要'。我认为语言需要建立在一个合理的模型上,而不是一大堆可能的技巧。

0 个答案:

没有答案