C++ C++/Java继承vs.委派vs.等等

C++ C++/Java继承vs.委派vs.等等,c++,inheritance,delegation,C++,Inheritance,Delegation,我正在创建一个类库,其中包含许多不同的选项,用于可能的自定义。例如,可以将类设计为可以执行FeatureX(),也可以将类设计为可以执行FeatureY() 在正常情况下,只需使用名为FeatureX的纯虚拟方法创建一个接口IFeatureX,然后使用名为FeatureY的纯虚拟方法创建另一个接口IFeatureY。如果一个类同时具有FeatureX和FeatureY,那么它可以从两者继承,这没有问题 我的问题是,如果一个函数/方法需要一个可以同时执行FeatureX()和FeatureY()的

我正在创建一个类库,其中包含许多不同的选项,用于可能的自定义。例如,可以将类设计为可以执行FeatureX(),也可以将类设计为可以执行FeatureY()

在正常情况下,只需使用名为FeatureX的纯虚拟方法创建一个接口IFeatureX,然后使用名为FeatureY的纯虚拟方法创建另一个接口IFeatureY。如果一个类同时具有FeatureX和FeatureY,那么它可以从两者继承,这没有问题

我的问题是,如果一个函数/方法需要一个可以同时执行FeatureX()和FeatureY()的对象,该怎么办?我如何在C++中表达一个类型,但是java中的一个答案也可以帮助,确保FeatureX和FeatureY都可用吗? 是否创建从IFeatureX和IFeatureY继承的另一个接口IFeatureXY?可以如果只有两个功能,我就可以摆脱它。但是如果有人说。。。10个功能,可能的接口数量变得庞大

有没有一个简单的方法可以做到这一点?我试着用C++模板和授权解决这个问题,但是没有太大的问题。我希望有一个简单的解决办法,也许有一个我刚刚忽略了

我感谢你们的帮助和建议


谢谢。

首先要做的是问自己是否在尝试做一些无法简单表达的事情,如果是,问问自己这是否真的值得做

考虑到你找不到一个更简单的模型来描述你想要的东西,你需要考虑这些选项之间的依赖关系。如果可以独立于功能部件Y使用功能部件X,则将其设置为独立的接口或纯虚拟类(视语言而定)


如果你不能独立使用它们,那就创建一个包含这两个元素的类;问问自己为什么要将FeatureX和FeatureY作为单独的接口,因为这种使用模式表明它们毕竟不是独立的。

首先要问的是,你是否正在尝试做一些无法简单表达的事情,如果是,问问自己是否真的值得做

考虑到你找不到一个更简单的模型来描述你想要的东西,你需要考虑这些选项之间的依赖关系。如果可以独立于功能部件Y使用功能部件X,则将其设置为独立的接口或纯虚拟类(视语言而定)


如果你不能独立使用它们,那就创建一个包含这两个元素的类;问问自己为什么要将Futuxx和FeatureY作为独立的接口,因为使用模式表明它们毕竟不是独立的。

< P>如果你想在C++中做,那么多重继承呢?< /P> < P>如果你想在C++中做,那么多重继承呢?

< P>你可能是太细了。考虑一个数值类——你可以执行乘法、除法、加法、减法等等。然而,你不会为这些操作中的每一个创建单独的接口——你将创建一个接口,称为SpPuthsStalm(或任何)覆盖它们的所有接口。

< P>你可能是过于细粒度。考虑一个数字类——你可以执行乘法、除法、加法、减法等等。然而,你不会为这些操作中的每一个创建单独的接口——你将创建一个接口,称为SpPuthsStalm(或任何)覆盖它们的所有接口。

< P>如果你不害怕使用模板,您可以将函数设置为模板,并使用SFINAE检查两个接口:

template <class T>
void my_function(const T& data, typename enable_if_c<
    is_convertible<T*, IFeatureX*>::value && 
    is_convertible<T*, IFeatureY*>::value>::type*=0) {
  ...
}
模板
void my_函数(const T&data,typename enable_if_c<
是否可转换::值&&
是否可转换::值>::类型*=0){
...
}
这将为扩展两个功能接口的每个类型创建一个方法(请注意,SFINAE技巧不需要它来工作;无约束的模板可以工作,但在传递不满足要求的类型时无法编译)

另一种可能是创建一个接口IFeatureXY,扩展两者,并在函数参数中使用它;这有一个缺点,即类型实现了两个接口,但此联合接口不能与此方法一起使用

此外,您可以向函数传递两个参数,每个接口一个,并要求它们是指向同一对象的指针;这是脆弱的,但可以通过创建一些模板类来保存这两个指针(例如,
product_type
)来进行硬化,这两个指针将由所讨论的单个对象初始化,并且将保存这两种类型


在Java中,您可能可以对有界类型变量执行相同的操作(如果它们允许多个边界;我现在不确定)。

如果您不怕使用模板,您可以将函数设置为模板,并使用SFINAE检查两个接口:

template <class T>
void my_function(const T& data, typename enable_if_c<
    is_convertible<T*, IFeatureX*>::value && 
    is_convertible<T*, IFeatureY*>::value>::type*=0) {
  ...
}
模板
void my_函数(const T&data,typename enable_if_c<
是否可转换::值&&
是否可转换::值>::类型*=0){
...
}
这将为扩展两个功能接口的每个类型创建一个方法(请注意,SFINAE技巧不需要它来工作;无约束的模板可以工作,但在传递不满足要求的类型时无法编译)

另一种可能是创建一个接口IFeatureXY,扩展两者,并在函数参数中使用它;这有一个缺点,即类型实现了两个接口,但此联合接口不能与此方法一起使用

此外,您可以向函数传递两个参数,每个接口一个,并要求它们是指向同一对象的指针;这是脆弱的,但可以通过创建一些模板类来保存这两个指针(例如,
product_type
)来进行硬化,这两个指针将由所讨论的单个对象初始化,并且将保存这两种类型

在Java中,您可能可以对b执行相同的操作
template< typename T >
void some_function( const T& t )
{
    // use featureX functions
    t.fetatureX();

    // use featureY functions
    t.featureY();
}
SomeClass x; // object with only X feature
some_function( x ); // compile time error, because featureY() doesn't exists