【问题标题】:win32 application aren't so object oriented and why there are so many pointers?win32 应用程序不是那么面向对象,为什么有这么多指针?
【发布时间】:2010-02-25 15:04:08
【问题描述】:

这对你们中的一些人来说可能是一个愚蠢的问题,也许我问错了这个问题,因为我是 C++ 新手。但是我注意到,在很多 Win32 应用程序中工作时,您会使用大量的指针资源。为什么你必须总是获取一个对象指针?为什么不启动该类的新实例。说到这一点,我注意到在大多数情况下,您从不启动新对象,而是总是调用返回该指针的方法。如果该指针正在其他地方使用怎么办。如果您更改该指针并且它正在其他地方使用,您不会搞砸一些事情吗?

【问题讨论】:

    标签: c++ c winapi


    【解决方案1】:

    Windows API 是为 C 设计的,它曾经是并且仍然是系统编程中最常用的语言; C API 是系统 API 的事实上的标准,为此几乎所有其他语言都有并且有一些方法可以调用外部 C 函数,因此编写 C API 有助于与其他语言兼容。

    C API 只需要一个简单的 ABI,它几乎只包含用于函数的调用约定的定义(以及一些关于结构布局的内容)。相反,C++ 和其他面向对象的语言需要一个复杂的 ABI,它必须定义对象在内存中的布局方式、如何处理继承、如何布局 vtable、如何传播异常、将 RTTI 数据放在哪里, ...此外,并非所有语言都是面向对象的,并且将 C++ 的 API 与其他非面向对象的语言一起使用可能会很痛苦(如果你曾经使用 C 中的 COM,你就会明白我的意思)。

    顺便说一句,在最初设计 Windows 时,C++ 在 PC 上并没有那么普遍,而且 C 也没有这么大量使用:实际上,Windows 3.11 的很大一部分和许多应用程序都是仍然是用汇编写的,因为那个时代的内存和 CPU 限制非常严格;编译器也没有现在那么聪明,尤其是 C++ 的。在手工组装通常是唯一解决方案的机器上,C++ 开销确实是不可接受的。

    对于指针的事情:Windows API 几乎总是使用句柄,即不透明的指针,以便能够在不影响现有应用程序的情况下更改每个资源的底层性质并阻止应用程序乱用内部结构。窗口管理器用来表示内部窗口的结构是否改变并不重要:所有应用程序都只使用一个 HWND,它总是指针大小。您可能会认为这是某种 PIMPL 习语。

    但是,Windows 在某种程度上是面向对象的(例如,参见整个“窗口类”概念,或者更深层次的 NT 内核的内部工作,它在很大程度上基于“对象”概念),但是它最基本的 API,作为简单的 C 函数,以某种方式隐藏了这种面向对象的性质。另一方面,多年后设计的 shell 主要是用 C++ 编写的,它提供了一个真正面向对象的 COM 接口。

    有趣的是,您可以在 COM 中看到在构建跨语言但仍偏向 C++ 的面向对象接口时必须面对的所有权衡:结果相当复杂,在某些方面很难看,而且使用起来并不简单语言。相反,Windows API 作为简单的函数通常更容易调用。

    如果您对基于 C++ API 的系统感兴趣,可以查看Haiku;就个人而言,这是我对该项目非常感兴趣的方面之一。

    顺便说一句,如果你打算只使用 API 进行 Win32 编程,你最好找一本好书来习惯这些“特殊性”和其他 Win32 习语。两个著名的是Rector-NewcomerPetzhold

    【讨论】:

    • 谢谢。从所有的回复中。现在更有意义了。
    • 很好的解释。但是有一个问题:如果 Win32 实际上是面向对象的,为什么在 WndProc 函数(可以说是整个 API 的核心)中获取实例指针如此困难? (参见codeguru.com/forum/printthread.php?t=234315
    • @Jared:Win32 API 或多或少面向对象的性质是与 C++ 类型系统无关的概念性事物。窗口类是窗口管理器的概念,而不是您用来访问 WM 功能的特定语言的概念。您可以在 C++ 类/对象与窗口类/实例之间创建对应关系,但原则上它们是完全不相关的东西。
    • 什么是 ABI?
    • @ViniDalvino 它是“应用程序二进制接口”,定义语言结构如何转换为机器代码/二进制数据布局的规则集。
    【解决方案2】:

    因为 Win32 Api 是用纯 C 编写的,而不是 C++。因此,几乎任何语言的任何程序都可以调用这些 API。

    另外,没有简单的机制可以跨不同的模块和不同的语言使用对象。 IE。你不能将 C++ 类导出到 python。当然,也有像 OLE/COM 这样的技术,但它们仍然是用纯 C 编写的。而且使用起来有点复杂。

    另一方面,对普通 C 函数的调用是标准化的。因此,您可以使用任何语言从 DLL 或静态库中调用例程。

    【讨论】:

      【解决方案3】:

      Win32 被设计为使用 C 语言而不是 C++。
      这就是为什么您会看到已定义的 BOOL 而不是 bool 的返回类型。
      bool 特定于 C++,在 C 中不存在。

      有关 Microsoft 面向对象的 Win32 包装器,请参阅MFC

      从那时起,微软推出了一个较新的框架,即 .Net Framework。
      .Net 框架虽然基于托管代码,但并不本机运行。在 Windows 上进行 GUI 编程的最现代方法是 WPF 甚至 Silverlight。

      进行非托管 GUI 编程的最现代方式仍然是使用 MFC,尽管有些人仍然更喜欢直接使用 Win32。

      注意使用指针并不是 C 特有的,它在 C++ 中仍然很常见。

      【讨论】:

      • @dpimka:发帖人专门询问 Win32。 MFC 离 Win32 不远,在这方面值得一提。
      • MFC 仍然是在 C++ 中实现 Windows 的官方 OO 方式,不是吗?
      • 今天确实如此,但在 1995 年,这是你能做的最好的事情 - 在 RTTI 之前,在信号之前,在 STL 之前。
      • @John,是的,今天确实没有在 Windows 上创建 C++ gui 的好方法。您可以将 winforms/WPF 与托管 C++ 或 Qt/wx 之类的东西一起使用。
      • MFC 还通过资源编辑器与 Visual Studio 进行了很好的集成。
      【解决方案4】:

      第一个原因是因为传递指针很便宜。指针在 x86 上为 4 个字节,在 x64 上为 8 个字节。虽然它指向的结构或类可以占用更多的内存。所以实例化一个类意味着一次又一次地保留新的内存。从速度和内存消耗 POV 来看,这效率不高。

      另一种方法是传递对对象或智能指针或类似结构的引用。但是win32 api是在C时代设计的,所以到现在为止;)

      关于指针的潜在混乱 - 当然有可能。但大多数情况下,它们的生命周期都在 API 中明确说明(如果不明显的话)。

      【讨论】:

        【解决方案5】:

        可能是因为 Win32 API 比主流的面向对象编程“更老”,它的核心不是 C++ API。

        【讨论】:

          【解决方案6】:

          这几乎就像您应该尝试许多 OO 包装器之一。像 MFC 或 .net。

          【讨论】:

          • .net 可以做的事情不在底层 API 中
          • 我主要是一名 C++ 开发人员,但即使是我也可以承认,.Net 无疑可以实现更快的开发和更少的错误代码。更不用说需要维护的原始代码更少了。
          • @Brian 我完全同意并且主要在 .net 中开发,但它是基于 win32 构建的。除了单声道的情况,但我认为这有点超出了讨论范围。
          • 是的,它可能在某种程度上使用了 Win32,但我不会说它是一个包装器。无论如何 +1。
          【解决方案7】:

          Windows API 是普通的旧 C,因此到处都使用指针。此外,您要求 Windows 提供新指针的原因是因为 Windows 需要跟踪所有对象......它分配事物并告诉您一个指针(或有时只是一个数字 ID)让您使用它们。

          【讨论】:

            【解决方案8】:
            • 将 C 函数作为 API 允许 C 和 C++ 程序员使用它。
            • Windows API 可以追溯到很久以前 - C 在那个年代很有名。

            所有的 HWND、HANDLE、HDC 都只是一个弱的尝试来制作钳制的、类似对象的数据类型(使用struct)。 C FAQ 对此有疑问 -> http://c-faq.com/struct/oop.html.

            【讨论】:

            • 拥有 C 函数允许大多数语言,包括 Python、Haskell 和 C#,也可以调用 Win32。 :)
            • +1 也提到了其他语言,C 在 ABI 方面具有通用性:)
            【解决方案9】:

            要了解您可能想要阅读的指针the CPlusPlus.com tutorial on pointers

            【讨论】:

            • 我理解指针。我只是不明白为什么 C 使用了这么多。如果有的话,了解 WIN32 系统程序的资源会有所帮助
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-13
            • 1970-01-01
            • 1970-01-01
            • 2016-12-27
            • 2010-09-18
            • 1970-01-01
            相关资源
            最近更新 更多