我将数据存储在从文件中读取的 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 ...
尽管此解决方案有效,但我相信它可以更容易地完成。我想出的任何其他更简单的解决方案都失败了,例如由于类型擦除。
我将不胜感激。谢谢!