我有两个不同的课程如下:
class text
{ };
class element
{ };
Run Code Online (Sandbox Code Playgroud)
我想将它们存储在class node:
template <typename T>
class node
{
T cargo;
std::vector<void*> children;
node(T cargo) : cargo(cargo)
{ };
void add_child(T node)
{
this->children.push_back((void*) node);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我会以这种方式调用节点存储两个,text并且element:
element div;
text msg;
node<element> wrapper(div);
wrapper.add_child(msg);
Run Code Online (Sandbox Code Playgroud)
编辑:要取回我使用的内容T typedef type;并将void指针转换为(type*).
我知道这不是很优雅也不实用,但我无法弄清楚这样做的正确方法是什么.所以请告诉我这是否实际可以接受,如果不是,那么如何以正确的方式做到这一点.
提前致谢!
#include <vector>
using namespace std;
class Element {};
class Text {};
class Nothing {};
class Node
{
private:
vector< Node* > children_;
protected:
Node() {}
public:
void add( Node* p ) { children_.push_back( p ); }
virtual ~Node() {}
};
template< class Cargo >
class CargoNode
: public Node
{
private:
Cargo cargo_;
public:
CargoNode(): cargo_() {}
};
typedef CargoNode< Element > ElementNode;
typedef CargoNode< Text > TextNode;
typedef CargoNode< Nothing > RootNode;
int main()
{
RootNode* root = new RootNode;
root->add( new ElementNode );
root->add( new ElementNode );
root->add( new TextNode );
root->add( new ElementNode );
// Etc.
}
Run Code Online (Sandbox Code Playgroud)
干杯&hth.,
PS:此示例代码中省略了错误检查,生命周期管理,迭代等.
我会说void*几乎总是"坏"(对于某些坏的定义).当然,可能有更好的方式来表达你正在尝试做的事情.如果是我编写这段代码并且我知道我要放入的值的类型,那么我会考虑使用Boost.Variant.如果我没有(例如,这是作为一个库提供给其他人"填满"),那么我会使用Boost.Any
例如:
template <class T, class U>
struct node
{
typedef boost::variant<T, U> child_type;
std::vector<child_type> children;
void add_child(T const &t)
{
children.push_back(t);
}
void add_child(U const &u)
{
children.push_back(u);
}
};
...
node<text, element> n;
n.add_child(text("foo"));
Run Code Online (Sandbox Code Playgroud)
非增强型联合解决方案:
struct node
{
struct child
{
int type; // 0 = text; 1 = element
union
{
text* t;
element* e;
} u;
};
std::vector<child> children;
void add_child(text* t)
{
child ch;
ch.type = 0;
ch.u.t = t;
children.push_back(ch);
}
void add_child(element* e)
{
child ch;
ch.type = 1;
ch.u.e = t;
children.push_back(ch);
}
};
Run Code Online (Sandbox Code Playgroud)
注意:对于使用类型联合的内存管理,您必须更加小心.