2013-02-12 82 views
1

似乎是一个很好的策略,撰写我的对象是这样的(如政策):如何避免虚拟继承

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*/}; 

这样,我可以谱写我ConcreteModel不同FluxTypeSourceType对象。

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

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

+0

顺便说一句,为什么[Smurf命名](http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html)? – Kos 2013-02-12 11:25:04

+0

可能是[CRTP模式](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)可能有助于您的情况,因此您可以在不需要虚拟继承的情况下混合使用各种实现。 – 2013-02-12 11:26:37

+0

@Kos thx,已更改 – dodol 2013-02-12 11:28:00

回答

1

嗯,很简单:你违反了LISKOV Substitution PrincipleConcreteFlux继承自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他们的方法。这就是外化是关于。