在std :: vector声明中使用void指针有多糟糕?

Riz*_*izo 0 c++ vector void

我有两个不同的课程如下:

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*).

我知道这不是很优雅也不实用,但我无法弄清楚这样做的正确方法是什么.所以请告诉我这是否实际可以接受,如果不是,那么如何以正确的方式做到这一点.

提前致谢!

Che*_*Alf 6

#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:此示例代码中省略了错误检查,生命周期管理,迭代等.


Kaz*_*gon 5

我会说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)

注意:对于使用类型联合的内存管理,您必须更加小心.