【问题标题】:How to avoid virtual inheritance如何避免虚拟继承
【发布时间】:2013-02-12 11:22:26
【问题描述】:

看起来像这样组合我的对象的好策略(作为策略):

template<typename FluxType, typename SourceType>
class Model : public FluxType, public SourceType
{ };
//later in the code:
template<typename FluxType, typename SourceType>
class ConcreteModel : public Model<FluxType, SourceType>
{};

但是,FluxTypeSourceType 是使用相同数据的类。所以我使用了虚拟继承:

class ConcreteModelProps{};
class ConcreteFlux : virtual public ConcreteModelProps
{};
class ConcreteFlux2 : virtual public ConcreteModelProps
{/*sligthly different implementation*/};
class ConcreteSource : virtual public ConcreteModelProps
{};
class DefaultSource2 
{/*no need for data*/};

这样我就可以用不同的FluxTypeSourceType 对象组成我的ConcreteModel

ConcreteModel<ConcreteFlux, DefaultSource2> /*or whatever*/.

事实上,ConcreteModelProps 中定义的数据与ConcreteModel 密切相关。在我看来,我至少做错了什么。我怎样才能使这个设计更好?最好没有虚拟继承? 谢谢,dodol

【问题讨论】:

  • 顺便说一句,为什么Smurf Naming
  • CRTP pattern 可能对您的情况有所帮助,因此您可以混合各种实现而不需要虚拟继承。
  • 您没有实现虚拟继承。编译器会这样做。您使用了虚拟继承。
  • @PeteBecker thx,已更正

标签: c++ templates multiple-inheritance


【解决方案1】:

嗯,很简单:你违反了LISKOV Substitution Principle,因为ConcreteFlux 继承自ConcreteModelProps;所以你付出代价才是正确的。

现在,如果您将数据外部化,您可以使用更健全的模型。

template <typename FluxType, typename SourceType>
class Model {
public: 
    typedef typename FluxType::DataType DataType;
}; // class Model

template <typename M>
class ConcreteModel: public M {
}; // class ConcreteModel

然后:

class ConcreteFlux {
public:
    typedef ConcreteModelProps DataType;
};

class ConcreteSource {
public:
    typedef ConcreteModelProps DataType;
};

template <typename Data>
class DefaultSource {
    typedef Data DataType;
};

最后:

class ConcreteModel<Model<ConcreteFlux, ConcreteSource>> {};

当然,这意味着现在ConcreteFluxConcreteSource 的所有方法都需要在它们的每个方法中传递ConcreteModelProps 的句柄。这就是外化的意义所在。

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 2019-02-04
    • 2016-03-19
    • 1970-01-01
    • 2016-10-26
    • 2016-12-13
    • 1970-01-01
    • 2013-08-24
    相关资源
    最近更新 更多