5
我將數據存儲在從文件讀入的C++樹形結構中。該樹看起來像這樣:在樹形轉換中合併模板和繼承
class BaseNode {
std::vector<BaseNode*> children_;
...
};
class WhiteNode : public BaseNode { ... };
class BlackNode : public BaseNode { ... };
樹建成後,我想轉換它,到一個字符串。
爲了保持樹代碼轉換代碼是分開的,我想用模板,即實現類似的東西:
template <class T>
T WhiteNode::Convert() { ... };
然而,由於樹節點存儲爲BaseNode*
,我不不知道如何訪問這樣的模板成員函數。由於模板成員函數不能被繼承,所以我認爲這不會起作用。
我沒有拿出一個有效的解決方案,但:
class BaseConversion {
public:
virtual ~BaseConversion() {}
virtual void * FromBlack() = 0;
virtual void * FromWhite() = 0;
};
template <class T>
class Conversion : public BaseConversion {
public:
void * FromBlack();
void * FromWhite();
};
class BaseNode {
std::vector<BaseNode*> children_;
virtual void * Convert(BaseConversion * conversion) = 0;
public:
virtual ~BaseNode() {}
template <class T>
T Convert() {
return *static_cast<T*>(Convert(new Conversion<T>));
}
};
class WhiteNode : public BaseNode {
void * Convert(BaseConversion * conversion) {
return conversion->FromWhite();
}
};
class BlackNode : public BaseNode {
void * Convert(BaseConversion * conversion) {
return conversion->FromBlack();
}
};
和轉換邏輯可完全獨立:
template <>
void * Conversion<std::string>::FromWhite() {
return new std::string("converting WHITE node to std::string ...");
}
template <>
void * Conversion<std::string>::FromBlack() {
return new std::string("converting BLACK node to std::string ...");
}
測試代碼:
BaseNode * node = new BlackNode;
std::cout << node->Convert<std::string>() << std::endl;
node = new WhiteNode;
std::cout << node->Convert<std::string>() << std::endl;
回報預期結果:
converting BLACK node to std::string ...
converting WHITE node to std::string ...
雖然這個解決方案有效,但我相信它可以更容易地完成。我提出的任何其他更簡單的解決方案都失敗了,例如由於類型擦除。
我將不勝感激任何幫助。謝謝!
感謝。避免void指針可能稍微更優雅。然而,我正在尋找更緊湊的東西,也許沒有轉換或訪問類。 – DonDieselkopf
這不會完全可行。你有C++ 11支持嗎? –
是的,我喜歡。如果有C++ 11解決方案,我會很好奇。我實際上期待着一些類似CRTP的解決方案。但看着我的應用程序,我越來越傾向於堅持使用訪問者模式。不過,任何其他意見都非常受歡迎。 – DonDieselkopf