C++ COM:如果我更改了一个接口的父接口,我需要创建一个新接口吗?

C++ COM:如果我更改了一个接口的父接口,我需要创建一个新接口吗?,c++,com,c++builder,C++,Com,C++builder,我一直在向COM接口添加新功能,从我所读到的内容来看,唯一的方法是创建一个继承旧接口的新接口并添加新方法。我尝试过这样做,但我的层次结构已经相当复杂了 假设我的界面目前是这样的: IBaseInterface | IDerivedInterface 易卜赛界面 | 理想驱动接口 我想向基本界面添加一些功能,现在看起来是这样的: IBaseOldInterface | IBaseInterface | IDerivedInterface IBaseInterface

我一直在向COM接口添加新功能,从我所读到的内容来看,唯一的方法是创建一个继承旧接口的新接口并添加新方法。我尝试过这样做,但我的层次结构已经相当复杂了

假设我的界面目前是这样的:

IBaseInterface | IDerivedInterface 易卜赛界面 | 理想驱动接口 我想向基本界面添加一些功能,现在看起来是这样的:

IBaseOldInterface | IBaseInterface | IDerivedInterface IBaseInterface INewInterface | IDerivedInterface
class TMyObject: public TInterfacedObject, IDerivedInterface, INewInterface
IBaseOldInterface | 易卜赛界面 | 理想驱动接口 因为我添加了这个新功能,我需要创建一个新的IDerivedInterface吗?我已经尝试过它目前的方式,它似乎不适合所有情况

我只是想确认一下,如果可能的话,解释一下原因

我需要进一步解释我的理想情况以及原因:

我想向IBaseInterface类添加一些方法,然后所有派生类都可以使用这些方法。我认为可能的是:

IBaseOldInterface / \ IDerivedOldInterface IBaseNewInterface \ / IDerivedNewInterface IBaseOldInterface / \ IDerivedOldInterface iBasene接口 \ / IDerivedNewInterface 我知道应该避免菱形继承,但它们只是接口,所以我认为这是可以的


当用户请求InewDerivedInterface之一时,使用此新结构。查询接口将返回该IID的正确接口,无论是INewDerivedInterface还是IoldDrivedInterface。

不起作用。正如您所说,为了保持兼容性,您不能修改已经发布的接口。但是通过更改继承,您正在修改接口

因此,您可以将新方法添加到新的子类中,然后您将拥有以下结构:

IBaseInterface | IDerivedInterface | IDerivedInterface2
这是行不通的。正如您所说,为了保持兼容性,您不能修改已经发布的接口。但是通过更改继承,您正在修改接口

因此,您可以将新方法添加到新的子类中,然后您将拥有以下结构:

IBaseInterface | IDerivedInterface | IDerivedInterface2
向基本接口添加方法(或用扩展它的另一个方法替换)会更改所有派生接口的vtable布局,因此确实需要使用新IID创建新的派生接口。

向基本接口添加方法(或用扩展它的另一个方法替换)会更改所有派生接口的vtable布局,因此,您确实需要使用新的IID创建新的派生接口。

有三种方法可以将新功能添加到您的
IBaseInterface
IDerivedInterface
接口:

  • 将新方法添加到
    IDerivedInterface
    的底部。知道这些新方法的新构建的应用程序将能够使用它们。早期构建的应用程序将继续安全地使用旧方法。您不能将方法添加到
    IBaseInterface
    ,也不能从另一个接口重新添加方法,因为这将改变依赖的方法。 从您最初问题的上下文来看,我感觉您正在更改一系列外部软件项使用的公共接口,并且您不希望您的更改导致任何问题。如果是这样的话,你可能会想克制自己不要走这条路,即使这条路看起来很简单,而且很好地完成了这项工作(见下面的原因)

  • 您可以从
    IBaseInterface
    IDerivedInterface
    派生新接口,新构建的应用程序将使用它。注意,不必为新接口分配新的IID

  • 您定义了新的接口(如上面@DavidHeffernan中的
    INewInterface
    ),您的COM对象只实现了更多接口。新构建的应用程序可以查询新接口并调用其方法

  • 上面的第3项可能是扩展对象的典型、简单和方便的方法。只有当您需要在“主”界面上保留方法时,项目2才有意义,例如,对于传统客户端,如VB6。第1项是一种在不太修改代码的情况下快速添加内容的方法,它也可以工作-唯一的问题是客户端无法安全地检测服务器是否只实现了旧方法,还是同时实现了新方法。

    有三种方法可以向
    IBaseInterface
    添加新功能,
    IDerivedInterface
    接口:

  • 将新方法添加到
    IDerivedInterface
    的底部。知道这些新方法的新构建的应用程序将能够使用它们。早期构建的应用程序将继续安全地使用旧方法。您不能将方法添加到
    IBaseInterface
    ,也不能从另一个接口重新添加方法,因为这将改变依赖的方法。 从您最初问题的上下文来看,我感觉您正在更改一系列外部软件项使用的公共接口,并且您不希望您的更改导致任何问题。如果是这样的话,你可能会想克制自己不要走这条路,即使这条路看起来很简单,而且很好地完成了这项工作(见下面的原因)

  • 您可以从
    IBaseInterface
    IDerivedInterface
    派生新接口,新构建的应用程序将使用它。注意,不必为新接口分配新的IID

  • 您定义了新的接口(如上面@DavidHeffernan中的
    INewInterface
    ),您的COM对象只实现了更多接口。新构建的应用程序可以查询新接口并调用其方法
  • 上面的第3项可能是扩展对象的典型、简单和方便的方法。只有当您需要在“主”界面上保留方法时,项目2才有意义,例如,对于传统客户端,如VB6。第1项是一种在不太修改代码的情况下快速添加内容的方法,它也可以工作-唯一的问题是客户端无法安全地检测服务器是否只实现了旧方法,还是同时实现了新方法。

    var
      Base2: IBaseInterface2;
    begin
      if Supports(AnyBaseOrDerivedInterfacePtr, IBaseInterface2, Base2) then
      begin
        // use Base2 as needed...
      end;
    end;