繁体   English   中英

C ++ / Java继承与委派与等等

[英]C++/Java Inheritance vs. Delegation vs. etc

我正在创建一个类库,其中包含许多可能的自定义选项。 例如,您可以设计您的类,使其可以执行FeatureX(),或者您可以设计您的类,使其可以执行FeatureY()。

在正常情况下,您只需使用称为FeatureX的纯虚拟方法创建接口IFeatureX,并使用称为FeatureY的纯虚拟方法创建另一个接口IFeatureY。 如果一个类同时具有FeatureX和FeatureY,则可以同时继承两者。

我的问题是,如果一个函数/方法需要一个可以同时执行FeatureX()和FeatureY()的对象怎么办? 如何最好用C ++表示类型,但是用Java回答也可以帮助确保FeatureX和FeatureY都可用?

是否创建另一个继承自IFeatureX和IFeatureY的接口IFeatureXY? 好的...如果只有两个功能,我可以解决。 但是,如果说... 10个功能,则可能的接口数量将变得庞大。

有没有简单的方法可以做到这一点? 我尝试使用C ++模板和委派来解决问题,但步步未定。 我希望对此有一个简单的解决方案,也许我只是忽略了一个。

感谢您提供的任何帮助和建议。

谢谢。

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

鉴于找不到所需的简单模型,您将需要考虑选项之间的依赖关系。 如果可以独立于功能Y使用功能X,则使它们成为独立的接口或纯虚拟类(视语言而定)。

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

如果您不担心使用模板,则可以将函数设为模板,并使用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) {
  ...
}

这将为扩展了两个功能接口的每种类型创建一个方法(请注意,不需要SFINAE技巧即可起作用;可以使用不受约束的模板,但是当您传递不满足要求的类型时,它将无法编译)。

另一种可能性是创建一个扩展两者的接口IFeatureXY,并在函数参数中使用它。 这样做的缺点是, 可以同时实现两个接口但不能实现此联合接口的类型不能用于此方法。

另外,您可以将两个参数传递给函数,每个接口一个,并要求它们是指向同一对象的指针。 这很脆弱,但是可以通过制作一些模板类来容纳两个指针来加强它-例如。 product_type<IFeatureX*, IFeatureY*> ,它将由所讨论的单个对象初始化,并且将包含两种类型。

在Java中,您可能会对有界类型变量做同样的事情(如果它们允许多个界限;我现在不确定)。

尽管有多种方法可以添加完全不同的功能,但是您可能需要考虑这些添加功能的范围。 它们将与您的主类库相关吗? (一个人可能会争辩说,如果不是,那么就不应成为其中的一部分)

如果它们有足够的共同点来保证添加功能,则可以寻找诸如装饰器模式( http://en.wikipedia.org/wiki/Decorator_pattern )之类的东西。 通过这种方式,您可以绕开一些棘手的问题。

如果您想用C ++做到这一点,那么多重继承又如何呢?

可能您的粒度太细了。 考虑一个数字类-您可以执行乘法,除法,加法,减法等。但是,您不会为这些操作中的每一个创建单独的接口-您将创建一个称为SupportsArithmetic的接口(或涵盖所有内容)。

WCF具有非常好的模式,该模式如何使用IExtensionCollection<T>.Find<E>()确定某些对象是否支持某些接口(或类IExtensionCollection<T>.Find<E>() IExtensionCollection

IFeatureX feature = argument.Find<IFeatureX>();

if (feature != null)
{
    // Find() returned an instance so there is an implementation
    // of IFeatureX available

   feature.FeatureX();
}

这样,您可以查询对象的某些接口。 IUnknown :: QueryInterface()中的COM +中使用了类似的方法。

为什么需要接口? 使用模板:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM