首页 > 解决方案 > Windows API 是面向对象的框架吗?

问题描述

在 Windows API 中创建控件对象(an HWND)时,不允许直接访问控件对象的成员,只能通过特定的函数访问,这是 OOP 的一个特点。

此外,Windows API 支持多态,例如我可以有以下功能:

void setHwndText(HWND hwnd)
{
    SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)"Hello World");
}

上面的函数可以改变很多类型的对象的文本,而不仅仅是一种类型,例如它可以改变窗口的标题、编辑控件的文本和按钮控件的标题。

我不知道 Windows API 是否支持继承,但即使不支持,我认为 OOP 中继承的主要目的是允许多态性,正如我所展示的那样,Windows API 确实支持多态性。

这是否意味着可以将 Windows API 视为面向对象的框架?

标签: coopwinapi

解决方案


Windows 中的文件和窗口句柄类似于流、Unix 中的文件描述符、FILEC 标准库中的指针等。this将不透明句柄传递给库函数和使用隐式指针调用成员函数之间存在相似之处。

另一个更接近的例子是您注册的窗口类RegisterClassEx()。这是句柄式 API 和 COM 之类的框架之间的过渡,每个人都同意它是“面向对象的”:您注册一个包含函数指针的结构,这很像虚函数表中的成员函数指针。您没有任何类型的类层次结构或要实现的接口选择。您没有覆盖默认实现,或者在覆盖其他方法时继承某些方法。您只是传递一个包含函数指针的结构。

区别可能会变得模糊。如果你看一下 Nicholas Wirth 设计的语言家族,Pascal 是一种受 Algol 启发的传统结构化命令式语言,而 Modula、Modula-2 和 Oberon 在面向对象的方向上实验性地发展。当时,这些中间语言被称为“基于对象的”。到 90 年代中期,Delphi 和 Object Pascal 等语言适合面向对象的范式。

但是,类似于 70 年代后期的库通常不被称为“面向对象”。特别是,它们没有继承的类层次结构。客户端应用程序本身也不管理实例,它们的创建和销毁是自动的,以防止内存泄漏。

当 C API 执行类似于多态性和继承的事情时,例如能够提供指向回调函数的指针,它以不同的方式执行。在传统的面向对象语言中,您将静态定义覆盖虚拟成员函数的窗口的派生类,而不是提供任意函数指针以进行回调(尽管与面向对象的访问者模式有一些相似之处)。

类似名称的“窗口类”之类的只是回调。尽管多态对象的所有实现都建立在包含函数指针的结构之上,但并非所有使用回调函数的程序都是面向对象的。一个更接近面向对象编程的示例是 Winsock 2 如何使套接字描述符成为一种特殊类型的文件描述符,可以将其传递给内核文件函数(使用强制转换)。如果我们有一个面向对象的 API 将成员函数重命名为全局函数,那么隐式this指针一个显式参数,然后将其转换为一个不透明的句柄,它仍然主要是面向对象的。它唯一会失去的是静态类型安全和封装。更类似于 OOP,我肯定会称之为 OOP,是组件对象模型及其后继者,其中对象实现接口。

有几个“面向对象”的 Windows API,包括 Microsoft 基础类、Borland 的对象 Windows 库、对象链接和嵌入、更新的组件对象模型和公共语言运行时库,甚至更新的 Windows 运行时。


推荐阅读