关于介绍C ++接口的文章的问题

时间:2010-01-28 09:55:59

标签: c++ class interface

我一直在阅读一篇关于C ++接口(http://accu.org/index.php/journals/233)的文章,我完全迷失了它所说的所有虚拟成员函数应该被私有的部分(标题为“强化分离”的部分)。对我来说根本没有意义。

根据作者的说法,代码是这样的:

class shape {
public:
  virtual ~shape();
  virtual void move_x(distance x) = 0;
  virtual void move_y(distance y) = 0;
  virtual void rotate(angle rotation) = 0;
  //...
};

class line : public shape {
public:
  line(point end_point_1, point end_point_2);
  //...
private:
  virtual ~line();
  virtual void move_x(distance x);
  virtual void move_y(distance y);
  virtual void rotate(angle rotation);
  //...
};

所以我们有一个纯粹的虚函数,它是公共的,它的实现(在行类中)是私有的。

有人可以解释一下如何调用move_x函数吗?它的访问说明符是私有的,如果我尝试这样做会导致错误:

line my_line(point(0,0), point(1,2));
my_line.move_x(-1); // does not compile

同样,说绘图界面(参见本文前面部分)也无法访问这些函数是正确的吗?

谢谢。

4 个答案:

答案 0 :(得分:6)

这个想法是你通过引用或指针shape来使用这些方法。

shape &s = my_line;
s.move_x(-1);

这可以通过“仅揭示你需要的东西”或作为一种自我记录的形式来证明。它证明了这些方法只是按照预期的方式调用。

答案 1 :(得分:4)

如果你有line对象的实例,你可能会想要调用它的方法。但是,如果你能够获得它们的唯一方法是通过询问它的shape接口,那么该对象看起来不像一个对象,更像是一个接口集合。

如果您想象实现多个接口的行,这会更有意义。

答案 2 :(得分:3)

此建议仅适用于同类层次结构 - 也就是说,派生类不引入新函数(可能除了构造函数)并且只是覆盖基类函数的层次结构。在这种情况下,您显然不需要直接使用line实例 - 只能通过指向shape的引用。

如果你的层次结构不太一致,那么这个建议就没有多大意义了:当派生类引入新函数或从另一个基类继承它们时,如何将它应用于案例?在这种情况下,您有时希望直接使用派生类的对象,这种建议只会带来不便。

进一步发展这个想法 - 在更多情境中更少激进和可用 - Herb Sutter Non-Virtual Interface(NVI)。

答案 3 :(得分:2)

我认为这篇文章很好地突出了这句话的基本原理:

  

现在,用户可以做的唯一事情   line是创建它的实例。所有   用法必须通过其界面 - 即   形状,从而强化更强   接口/实现分离。   在离开这个主题之前,它是   得到一些直线的重要事项:   强制执行的要点   接口/实现分离是   不告诉用户该做什么。相反,   目标是巩固   逻辑分离 - 现在的代码   解释说,关键的抽象是   形状,并且该线用于提供   形状的实现。

也就是说,line本身并不有趣。它只是shape接口的一个实现,可能还有其他实现。您对shape界面特别感兴趣。因此,您应该只通过此接口访问实现,而不是作为独立的类。