我有一般设计问题。我正在尝试实现这样的事情:
------------
|Base Class|
------------
|
------------------
| |
----------- -----------
|SubClass1| |SubClass2|
----------- -----------
| |
-------------- --------------
|SubSubClass1| |SubSubClass2|
-------------- --------------
其中基类提供虚函数,子类是实现,子子类为实现提供常量。
我想过两次使用“奇怪的重复模板模式”:
// 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()。
类似于kosher的东西还是有更好的方法来做这样的事情?
提前多多感谢。
答案 0 :(得分:3)
这样做很好,我认为这样做没有任何普遍的缺点。我只是没有得到你实际使用CRTP的地方以及为什么简单的虚拟继承不适用于你的用例(CRTP通常用作静态多态)。
也不明白你的意思
private1(double, double);
你的subclass1
中的你的意思是构造函数吗?实际上它不会编译(除了构造函数或析构函数之外不允许返回值的函数)。
另一个批评者是:如果你指的是常数,你应该在你的子类中声明const
或static const
成员。
由于您没有明确指出您的特定用例,因此很难说出最适合它的设计。我可以提供另一种尝试跟随您的想法的方法:< / p>
// 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) {
// ...
}
};
// 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
}
};
// 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);
消除基类中的纯虚方法定义,并使用静态接口('traits')替换subclass
模板参数。