OO Langugage中的继承与句柄

Inheritance vs Handle in OO Langugage

本文关键字:句柄 继承 Langugage OO      更新时间:2023-10-16

接口和句柄之间的区别是什么

句柄-实现在另一个类中(句柄:显示一个类的所有功能,但实际实现是在另一类中编码的。句柄包含指向实现类的指针(pimpl习惯用法)。句柄就像一个包装类。)

接口-实现在派生类中

这是唯一的区别吗?

我们在哪里使用Interface,在哪里使用Handle?

C++不包括接口或句柄的概念,因此特别是在这种语言中,从技术上讲,说它们就是你对它们的理解是正确的。

也就是说,听起来这些概念有点混乱(没有权威定义的事实当然没有帮助)。

通常,句柄是某种唯一描述对象的值,但它的操作方式对于持有句柄的人来说是未知的。相反,有一些第三方知道如何从句柄到实际对象再返回,持有者必须在需要访问实际对象时通过该实体。这正是句柄的基本原理(从第三方的角度来看):除非你知道,否则你不希望别人弄乱你的对象,所以你把它们藏在不透明的句柄后面。

试图定义一个接口更困难,因为根据上下文的不同,有很多好的候选者:

  • 我们可以说,类的接口是其公共方法及其签名的集合;如果给你一个该类的实例,你就必须使用它
  • 我们也可以说,一个只有public virtual方法而没有数据成员的类是一个接口,因为它为两个实体之间的契约建模("你只允许调用这个方法,但当你这样做时,我保证会这样响应")

如果你想要一个更具体的答案,你必须首先与自己澄清这个问题,然后与我们其他人澄清。

"句柄"在C++方面没有广泛认同的含义。不同的人用它来表示完全不同的东西(例如,在Windows上,"句柄"确实有一个定义明确的含义,所以用C++编程Windows的人倾向于像Windows那样使用它)。

至于在另一个类中的实现,这听起来更像是一个皮条客,而不是大多数人通常所说的句柄。如果这就是你所说的事情,那么它在实现和使用方面都与继承有很大不同。事实上,在很多方面都是相反的:继承允许将彼此不同的类视为相同的类。对于皮条客,你有两个类(在某些方面)是相同的,但你仍然将它们完全分开。

至于你在哪里/为什么使用它们:通过一个接口(通常是C++中的ABC),你可以通过一个现有的接口操作新的派生类,这样现有的代码就可以使用你的新代码,而不需要修改现有的代码

pimpl通常主要用作编译器防火墙——如果你有一些代码经常更改,但不想每次更改时都重新编译依赖它的所有内容,那么pimpl可能会有所帮助(尽管绝对不是万能药)。

句柄通常用于表示不透明的数据类型——一种"神奇的cookie",它允许您访问某些功能,但您根本无法/根本无法直接查看或操作这些功能。在某种程度上,您可以将指向几乎任何类的任何引用/指针视为句柄(某种程度上),但以这种方式听到/看到这个术语是非常罕见的。更常见的情况是,它类似于C中的FILE *——当您调用fopen时,它会给出FILE *。每当您想对打开的句柄进行操作时,都会将相同的FILE *传递回要使用的函数。然而,你永远不应该从"内部"看它指向什么,它是如何使用的,或者其他任何东西(在Unix级别,使用open/lsek/lread等,文件描述符的方式基本相同)。

也许你想到的是在相对早期的C++中流行的句柄/主体习惯用法。在这个成语中,您确实在另一个类中实现了。具体来说,"句柄"通常提供引用计数,而主体则提供对具有多个(计数的)引用的单个项目所需的任何操作的实现。句柄"处理"了引用计数,并将几乎所有其他内容传递给实现类。这种用法不再常见,原因很简单,即引用计数在很大程度上已经失宠。特别是在多线程环境中,引用计数可能(而且经常)会带来相当大的速度损失,因此它的使用现在相对不常见(曾经几乎是大多数可能管理大量数据的类的预期)。