更多 C++ 习语/接口类
外观
- 将类的接口与其实现分离。
- 使用运行时多态调用抽象/类的实现。
将类的接口与其实现分离是高质量面向对象软件设计/编程的基础。对于面向对象编程,分离的主要机制是接口类。然而,C++(与 Java 相比)没有提供专门的机制来表达这种分离。在 Java 中,interface 关键字用于指定抽象支持的公共方法。C++ 没有这样的关键字,但可以使用接口类习语来近似表达其功能。这个想法是只表达抽象的公共方法,并且不提供任何方法的实现。此外,缺乏实现意味着不允许创建接口类的实例。
接口类只包含一个虚析构函数和纯虚函数,从而提供了类似于其他语言(如 Java)的接口构造。接口类是指定多态接口(即纯虚函数声明)到基类的类。使用类层次结构的程序员可以通过一个基类来进行操作,该基类只与层次结构中的类的接口进行通信。
class shape // An interface class
{
public:
virtual ~shape() {};
virtual void move_x(int x) = 0;
virtual void move_y(int y) = 0;
virtual void draw() = 0;
//...
};
class line : public shape
{
public:
virtual ~line();
virtual void move_x(int x); // implements move_x
virtual void move_y(int y); // implements move_y
virtual void draw(); // implements draw
private:
point end_point_1, end_point_2;
//...
};
int main (void)
{
std::vector<shape *> shapes;
// Fill up shapes vector somehow.
for (std::vector<shape *>::iterator iter (shapes.begin());
iter != shapes.end();
++iter)
{
(*iter)->draw();
}
// Clean up shapes vector. (Normally we would use something like std::unique_ptr to automate cleanup,
// this is for illustration only)
}
每个接口类都应该有一个虚析构函数。虚析构函数确保当以多态方式删除形状时,调用派生类的正确析构函数。否则,很有可能发生资源泄漏。使用接口类表达设计有很多好处。
- 可以添加新的形状抽象,而无需更改只依赖形状接口的代码。例如,Square 可以继承自 shape,并在其自己的方式中实现接口方法。main() 函数根本不需要更改。
- 将接口与实现分离可以防止重新编译只依赖接口类的程序部分。
- 依赖倒置原则 (DIP) 指出实现类不应该相互依赖。相反,它们应该依赖于使用接口类表示的共同抽象。DIP 减少了面向对象系统中的耦合。
几乎所有用 C++ 编写的良好面向对象软件!