【问题标题】:Comparing pimpl idiom with Microsoft COM将 pimpl idiom 与 Microsoft COM 进行比较
【发布时间】:2015-10-05 13:00:46
【问题描述】:

我知道这个话题在 StackOverflow 上有点离题。但是我实在想不出另一个更合适的地方来发帖,我真的很想收集你们的意见。

最近,我遇到了pimpl idiom。我认为这与微软的Component Object Model (COM)有关,并试图对两者进行比较。这样的比较应该有利于理解,我想确保我做对了。因此,如果您在比较中发现任何误解或有任何补充,请随时将其发布为答案。对比如下:

相似之处:

  1. 这两个接口都从二进制实现中解耦 等级。因此,更改实现不需要 重新编译用户代码。

区别:

  1. 由于 COM 接口只使用虚函数,用户代码可以 独立编译和链接,无需参考 以任何方式实施。这使二进制模块(即 .dll 在 Windows 上和.so 在 Linux 上)的实现是 在进程运行期间根据需要动态加载(例如,通过 在 Windows 平台上显式调用 LoadLibrary())。随着 pimpl 成语,类方法不一定是虚拟的,用户 代码链接必须引用实现,否则会有 未解析的外部符号引用。此外,加载 实现二进制模块必须在进程中隐式完成 由操作系统加载程序启动。

  2. pimpl 习惯用法允许直接实例化实现对象 在用户代码中。但是,对于 COM,必须使用工厂函数 获取指向实现对象的指针。

  3. 虽然 COM 设计为与编译器无关,但 pimpl 习惯用法不是 因为名字修改等等。

【问题讨论】:

  • 我投票决定将此问题作为离题结束,因为它可能更适合作为 wiki 主题
  • @Roy 关于我应该在哪里发布这样的内容有什么建议吗?
  • 遗憾的是没有。我确实将鼠标悬停在 “属于另一个站点” 单选按钮选项上,但想不出一个。除此之外,我认为这不是一个的问题。 :)
  • PIMPL 的目标很简单:隐藏类的实现细节以获得更好的封装。 COM 更加宏大:它使对象能够支持多个接口,并允许这些对象存在于同一个可执行文件、DLL、不同的可执行文件或完全不同的机器上,而无需了解调用代码的区别。
  • @MarkRansom 我同意。 COM 比 pimpl 成语要全面得多。我主要关注二进制接口(防火墙)方面。无论如何,您是否发现问题中给出的差异有任何误解?

标签: c++ interface com dynamic-linking pimpl-idiom


【解决方案1】:

两者都是对代码中允许的构造的自愿限制,以实现特定目标。

两者的共同点是,它们强制区分纯数据结构(不能包含方法)和对象接口(不能包含数据成员)。

此外,COM 还要求数据和接口参数是可序列化的(有一些例外,例如 IUnknown 不是),并且还为使用 GUID 的类和指定数据结构和虚拟的二进制接口引入了第二种命名约定功能表布局。

pimpl 习惯用法也使用工厂类——pimpl 类创建实际的实现。 COM 只是明确地将它们称为工厂类,并允许重用对象(例如,提供单例的工厂类简单地返回对自身的引用是合法的)。

就我个人而言,我觉得 pimpl 成语是不必要的。持有实现指针的类是一个相当冗长的智能指针类,它显式复制所有方法,与auto_ptr 相比,它为具有virtual 析构函数的抽象类提供的唯一优势是它允许使用. 代替-> 访问方法。

COM 添加新功能:

  • 方法调用可以编组并传输到不同的执行上下文
  • 所有对象都包含一个引用计数器,它允许在非合作上下文之间共享对象
  • 运行时分派是通过 GUID 执行的,只要旧的 GUID 仍被识别并加载了兼容层,它就允许更改接口定义而不会出现兼容性问题
  • 对象可以由不同的子对象组成,但在调用者看来是一个更大的单个对象。
  • 通用二进制接口和内存分配限制允许在使用不同编译器生成的代码之间进行调用,甚至可以链接到运行时的不同实现

编组方面是最重要的方面,因为被调用者的执行上下文可能是提供系统服务的不同的特权进程。

【讨论】:

  • 您能否详细说明它们在实际用途(功能)方面的一些区别?
猜你喜欢
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 2011-02-22
  • 2015-05-31
  • 2013-05-04
相关资源
最近更新 更多