我想寫一些字符串包裝,將接受一個字符串,如果它是有效的將其類型:重構到模板
Length
有效字符串:毫米,男,英尺,在Angle
有效字符串:度,弧度
我想象一個使用,如:
Length len = read_from_keyboard(); // or some means of initialization
if(len.is_valid()) { ... }
所以我寫了這些實現。
struct Length
{
QString m;
Length() {}
Length(QString s) { if(is_valid_string(s)) { m = s; } }
QString operator()() { return m; }
bool is_valid() { return is_valid_string(m); }
static bool is_valid_string(QString s) {
return s == "mm" || s=="m" || s=="ft" || s=="in";
}
};
和
struct Angle{
QString m;
Angle() {}
Angle(QString s) { if(is_valid_string(s)) { m = s; } }
QString operator()() { return m; }
bool is_valid() { return is_valid_string(m); }
static bool is_valid_string(QString s) {
return s == "deg" || s=="rad";
}
};
這在我看來,某種形式的靜態多態性,以is_valid_string()
他們在執行唯一的區別。
由於我有一些這些類,我想使用靜態繼承(而不是通過虛擬)來掌握常用功能。
於是,我想到了使用奇異遞歸模板模式的:
template <class T>
struct ConstrainedText {
QString m;
ConstrainedText() {}
ConstrainedText(QString s) { if(T::is_valid_string(s)) { m = s; } }
QString operator()() { return m; }
bool is_valid() { return T::is_valid_string(m); }
};
struct Angle : public ConstrainedText<Angle> {
static bool is_valid_string(QString s) {
return s == "deg" || s="rad";
}
};
struct Length : public ConstrainedText<Angle> {
static bool is_valid_string(QString s) {
return s == "mm" || s="m" || s=="ft" || s=="in";
}
};
但現在我已經失去了基類中隱含的構造,我不得不重寫他們!
有沒有我可以以具有相同的接口[default constructor
,implicit constructor
和is_value()
],只有實現這個任何其他方式寫的不同部分(靜態is_valid_string()
)最少的代碼?
我知道我可以使用預處理器,但我希望代碼對調試器友好。
我的問題是不是真的如何繼承的構造函數,但如何寫一個重構,這樣我只需要實現每個子類中is_valid_string()函數。 –