Curiously Recurring Template Pattern times two
我有一般设计问题。我正试图实现这样的功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 | ------------ |Base Class| ------------ | ------------------ | | ----------- ----------- |SubClass1| |SubClass2| ----------- ----------- | | -------------- -------------- |SubSubClass1| |SubSubClass2| -------------- -------------- |
当基类提供虚拟函数时,子类将实现分类,子类将常量提供给实现。
我考虑过两次使用"奇怪的重复模板模式",如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | // header baseclass.h template <typename subclass> class baseclass { private: public: virtual double GetQuantity1(double given1, double given2) = 0; virtual double GetQuantity2(double given1) = 0; } // header subclass1.h template <typename n> class subclass1:public baseclass<subclass>{ private: private1(double, double); public: double GetQuantity1(double given1, double given2); double GetQuantity2(double given1); } // header subsubclass1.h class subsubclass1:public subclass1<subsubclass1>{ private: public: double constant1; double constant2; } |
然后,在使用代码时,我将调用subsubclass::getQuantity1()。
有没有更好的方法可以做到这一点?
提前多谢。
这样做很好,我看不出这样做的任何一般缺点。我只是不知道您实际使用crtp的位置,以及为什么简单的虚拟继承对于您的用例不起作用(crtp通常被用作静态多态性)。
也不要明白你的意思
1 | private1(double, double); |
在你的
另一个批评是:如果您指的是常量,那么应该在子类中声明
由于您没有明确指定您的特定用例,很难说什么才是它的最佳设计。我可以提供从尝试遵循您的想法中获得的另一种选择:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // header baseclass.h template <typename subclass> class baseclass { public: inline double GetQuantity1(double given1, double given2) { // may be add a static check for GetQuantity1_Impl with a traits // check on subclass. return static_cast<subclass*>(this)->GetQuantity1_Impl(given1,given2); } inline double GetQuantity2(double given1) { return static_cast<subclass*>(this)->GetQuantity2_Impl(given1); } // You also can provide default implementations, otherwise the interface // method will be required from subclass to compile correctly inline double GetQuantity1_Impl(double given1, double given2) { // ... } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // header subclass1.h template<double const1, double const2> class subclass1:public baseclass<subclass1>{ public: subclass1() {} double GetQuantity1_Impl(double given1, double given2) { return 0.0; // Apply formula using the constants instead of 0.0 } double GetQuantity2_Impl(double given1) { return 0.0; // Apply formula using the constants instead of 0.0 } }; |
1 2 3 4 5 6 7 | // Client implementation file // No need for subsubclass1 just instantiate for usage subclass1<0.3, 3.1415> myAlgo; // A client calls the public interface of the (implicit) base class double result1 = myAlgo.GetQuantity1(23.2,42); double result2 = myAlgo.GetQuantity2(2.71828); |
消除基类中的纯虚拟方法定义,并用