2016-04-26 8 views
2

私の仕事は、さまざまな量のプロパティで構成されるデバイスの仕様クラスを定義することです。たとえば、Device1仕様にはProperty1、Property2が含まれています。他のDevice2にはProperty1のみ、DeviceX仕様にはProperty5、Property6などが含まれています。類似のクラスを実装する方法

これらのsetPropertyメソッドの同様の実装を繰り返すことを避けるために、それらを別々のクラスに格納し、それらの中から仕様を抽出することにしました。

CRTPイディオムを使用した特殊なメソッドを含む非常に似たクラスがたくさんあります。 CRTPは、仕様クラスのsetParameterを使用する方法にアクセスするために使用される:

template<typename SPECIFICATION> 
struct Property1 
{ 
    void setProperty1(const double & Value) 
    { 
     static_cast<SPECIFICATION*>(this)->setParameter("Property1", Value); 
    } 
}; 

template<typename SPECIFICATION> 
struct Property2 
{ 
    void setProperty2(const double & Value) 
    { 
     static_cast<SPECIFICATION*>(this)->setParameter("Property2", Value); 
    } 
}; 

これらのテンプレートクラスは、次いでCRTPイディオムに対してで使用される:デバイスの、上記のコードから見えるよう

template<typename DEVICE_TYPE> 
class Device 
{ 
public: 
     class Specification; 
}; 

template<> 
class Device<DeviceTypeAAA>::Specification 
     : public Property1<Specification>, 
      public Property2<Specification> 
{ 
}; 

template<> 
class Device<DeviceTypeBBB>::Specification 
     : public Property1<Specification> 
{ 
}; 

template<> 
class Device<DeviceTypeCCC>::Specification 
     : public Property2<Specification> 
{ 
}; 

仕様は、必要なプロパティーの継承を使用して「アセンブル」されます。すべてのデバイスは、Device :: Specificationの特殊なクラスです。 "setProperty"メソッドと非常に多くのDevice specificationクラスを実装する "Property classes"が実際にたくさんあるので、このようなクラスのクラスをより効率的に実装する方法があるかどうかは分かりません。私はboost :: mpl :: vectorを使って、ブーストリニアな継承と協力して、デバイスが導出するすべてのプロパティのリストを定義することを考えました。おそらく、私は完全に間違った方向にこれを実装しています。あなたがそう思ったら教えてください。

実装を最適化する方法を知っていれば、私は非常にうれしいです。助けてくれる誰にも感謝します!

答えて

0

以下の実装はvariadicsテンプレートを使用しますが、おそらく長い継承のスタックにつながりますが、それは問題ではありません。

それ以外は、プロパティのリストを使用して1つの継承宣言に指定の定義を縮小します。

コンパイルしてGCC 4.7(C++ 11)以上、さらには3.8でうまく動作します。

#include <iostream> 
#include <string> 

template<typename SPECIFICATION> 
struct Property1 
{ 
    void setProperty1(const double & Value) 
    { 
     static_cast<SPECIFICATION*>(this)->setParameter("Property1", Value); 
    } 
}; 

template<typename SPECIFICATION> 
struct Property2 
{ 
    void setProperty2(const double & Value) 
    { 
     static_cast<SPECIFICATION*>(this)->setParameter("Property2", Value); 
    } 
}; 

template<typename SPECIFICATION, template<typename> class ... PROPERTIES> 
struct Properties; // primary-template 

template <typename SPECIFICATION, 
      template<typename> class PROPERTY, 
      template<typename> class ... PROPERTIES> 
struct Properties<SPECIFICATION, PROPERTY, PROPERTIES...> : 
     PROPERTY<SPECIFICATION>, 
     Properties<SPECIFICATION, PROPERTIES...>{}; // head specialisation 

template <typename SPECIFICATION, 
      template<typename> class PROPERTY> 
struct Properties<SPECIFICATION, PROPERTY> : 
     PROPERTY<SPECIFICATION>{}; // tail specisalization 

template<typename DEVICE_TYPE> 
class Device 
{ 
public: 
     class Specification; 
}; 

struct DeviceTypeAAA{}; 
struct DeviceTypeBBB{}; 
struct DeviceTypeCCC{}; 

template<> 
class Device<DeviceTypeAAA>::Specification 
     : public Properties<Specification, Property1, Property2> 
{ 
    public: 
    void setParameter(const std::string &name, double value){ 
     std::cout << "DeviceTypeAAA: " << name << " = " << value << "\n"; 
    } 
}; 

template<> 
class Device<DeviceTypeBBB>::Specification 
     : public Properties<Specification, Property1> 
{ 
    public: 
    void setParameter(const std::string &name, double value){ 
     std::cout << "DeviceTypeBBB: " << name << " = " << value << "\n"; 
    } 
}; 

template<> 
class Device<DeviceTypeCCC>::Specification 
     : public Properties<Specification, Property2> 
{ 
    public: 
    void setParameter(const std::string &name, double value){ 
     std::cout << "DeviceTypeCCC : " << name << " = " << value << "\n"; 
    } 
}; 


int main() 
{ 
    Device<DeviceTypeAAA>::Specification a{}; 
    Device<DeviceTypeBBB>::Specification b{}; 
    Device<DeviceTypeCCC>::Specification c{}; 

    a.setProperty1(2.); 
    a.setProperty2(2.); 

    b.setProperty1(2.); 
    b.setProperty2(2.); // compiler error, no member setProperty2 

    c.setProperty1(2.); // compiler error setProperty1 
    c.setProperty2(2.); 


} 
関連する問題