C++ 如何从基类容器中提取派生类?
在使用公共父类将不同类型的对象存储在同一容器中之后,我需要将它们提取回来 [Tests/test0.c++]:C++ 如何从基类容器中提取派生类?,c++,templates,class,casting,C++,Templates,Class,Casting,在使用公共父类将不同类型的对象存储在同一容器中之后,我需要将它们提取回来 [Tests/test0.c++]: int main() { element wrapper; wrapper.name = "div"; wrapper.attributes["id"] = "wrapper"; cargo<string> text("Learn from yesterday, live for today, hope for tomorrow.");
int main()
{
element wrapper;
wrapper.name = "div";
wrapper.attributes["id"] = "wrapper";
cargo<string> text("Learn from yesterday, live for today, hope for tomorrow.");
wrapper.children.push_back(&text);
cout << "Name:\t" << wrapper.name << endl;
/* I have an explicit cast here,
* but it can't be used this way
* since children may have different types
*/
cout << "Cargo:\t" << ((cargo< string >*) wrapper.children[0])->value << endl;
return 0;
}
[Source/cargo.h]
struct element
{
std::string name;
std::map< std::string, std::string > attributes;
std::vector< node* > children;
};
struct node
{ };
template <typename Type>
struct cargo
: public node
{
Type value;
cargo(Type value)
: value(value)
{ }
};
模板
结构货物
:公共节点
{
类型值;
货物(类型值)
:值(value)
{ }
};
我需要某种类型的类型保持器与实际节点类型关联,并在进一步的强制转换提取操作中使用它。。。而不是我测试中那个硬编码的
更新:
我试图做的是一个简单的文档对象模型数据结构,将其用作类似xml的语言解析器的符号表条目。我不想使用任何现有的XML库,因为它们非常大。我认为DOM的思想很简单,因此我可以轻松地将其用于一些更复杂的操作,例如,通过使用cargo
允许DOM树中的节点使用泛型类型。我承认我采用的设计可能不是最合适的!所以我愿意接受建议
我将感谢任何帮助 如果只是流式处理,则可以在基类中实现流操作符,然后将其委托给派生类中的方法,否则请查看访问者模式。如果没有真正掌握您可能在
货物上执行的操作类型,就很难提出进一步的建议…如果您只是流式处理,您可以在基类中实现流操作符,然后将其委托给派生类中的方法,否则请查看访问者模式。如果没有真正掌握您可能在货物上执行的操作类型,就很难提出进一步的建议…如果您不打算在检索时以多态方式处理容器成员,以确定的方式包装容器成员可能会很有用
变量类模板是一个安全的,
通用的、基于堆栈的鉴别
union容器,提供了一个简单的
操作对象的解决方案
从中的一组异构类型
统一的方式。鉴于标准
诸如std::vector之类的容器可能是
被认为是“多元价值,单一价值”
类型,“变体”是多类型、单
价值观。”
中有一些示例代码。如果您不打算在检索时以多态方式处理容器成员,那么以确定性方式包装容器成员可能会很有用
变量类模板是一个安全的,
通用的、基于堆栈的鉴别
union容器,提供了一个简单的
操作对象的解决方案
从中的一组异构类型
统一的方式。鉴于标准
诸如std::vector之类的容器可能是
被认为是“多元价值,单一价值”
类型,“变体”是多类型、单
价值观。”
中有一些示例代码。如果没有演员阵容,您将无法处理类似的问题
但最重要的是,这往往意味着你走错了方向。只要您决定货物
将从节点
公开继承,您就在这两个类之间提供了一种非常紧密的关系,“成为节点
”的含义就比:
我可以插入一个容器中
以及其他节点
派生类型
我们需要知道什么是节点
,以及可以用它做些什么来进一步帮助您。然而,如果你真的需要坚持最初的解决方案,我可以帮你。如果没有演员阵容,你将无法处理类似的事情
但最重要的是,这往往意味着你走错了方向。只要您决定货物
将从节点
公开继承,您就在这两个类之间提供了一种非常紧密的关系,“成为节点
”的含义就比:
我可以插入一个容器中
以及其他节点
派生类型
我们需要知道什么是节点
,以及可以用它做些什么来进一步帮助您。但是,如果您真的需要坚持最初的解决方案,它可以帮助您。您应该进行设计,使代码不关心基类类型。提供一个对所有人都相同的接口。或者将您需要的纯虚拟方法添加到基类并在派生类中实现
假设这是不可能的,你试过动态施法吗?如果强制转换失败,它将返回null,而不是像上面的静态\u强制转换那样抛出
希望这有帮助,
Beezler您应该进行设计,使代码不关心基类类型。提供一个对所有人都相同的接口。或者将您需要的纯虚拟方法添加到基类并在派生类中实现
假设这是不可能的,你试过动态施法吗?如果强制转换失败,它将返回null,而不是像上面的静态\u强制转换那样抛出
希望这有帮助,
比兹勒
这个问题可能更多的是关于设计而不是实现。
尽管Boost.Variant和Boost.Any都可以工作,但它们只是一种变通方法。真正的问题可能是从节点类派生的类的可变责任部分没有封装。
你可以试着用构图代替。一个主机类用于公共接口和适当数量的组件/委托/任何内容(这些将从解决方案设计中产生:)
或者。。。一个完全不同的解决方案可能适合你。您可能想冒险使用元编程word,放弃通用接口。相反,元组(类型列表)等实体可能会有所帮助
致以最诚挚的问候,
马尔金
这个问题可能更多的是关于设计而不是实现。
尽管Boost.Variant和Boost.Any都可以工作,但它们只是一种变通方法。真正的问题可能是,派生自节点类的类的责任的可变部分不可用