【问题标题】:C++ Container defined in construction构造中定义的 C++ 容器
【发布时间】:2018-02-25 19:30:06
【问题描述】:

我可能以错误的方式问这个问题,但我想在对象实例化时定义一个成员容器。

namespace GUI {

class MenuNode {
    template <typename TMenuItem>
    struct MenuItem{
        TMenuItem *text;
    };
    MenuItem<unknown> t;//The member where I want the container
                        //to be defined upon construction
public:
    std::vector<MenuNode*> forward;
    MenuNode* parent;
    MenuNode();
    ~MenuNode();
};
}

我可以避免这个问题的一种方法是让 MenuNode 本身成为一个模板类,但是我将拥有带有所需容器(链表样式)的前向和后向指针,而且我也不知道它们的容器类型!

namespace GUI {
template<class MenuItem>
class MenuNode {
    MenuItem t;
public:
    std::vector<MenuNode<unknown>*> forward;    //Here I wouldn't know
                                                //what the container will
                                                //even be!
    MenuNode<unknown>* parent;        //same with this member
    MenuNode();
    ~MenuNode();
};
}

因此,另一种选择是拥有一个指针类型,它可以指向一个地址,而不管成员的容器是什么

namespace GUI {
template<class MenuItem>
class MenuNode {
    MenuItem t;
public:
    std::vector<void*> forward;
    void* parent;     
    MenuNode();
    ~MenuNode();
};
}

但是 void 指针的问题是我不知道如何确定对象所持有的容器类型!另外,我从来没有使用过 void 指针!

如果解决方案是在我创建具有非常相似功能(相同名称)的 MenuItem 时使用 void 指针,我可以通过取消引用 void 指针来调用它们。

【问题讨论】:

  • 如果您使用的是 c++17,另一种选择是使用 std::any,如果不是,则使用 boost::any。如果您提前知道所有类型,还有std::variant (c++17) 和boost::variant

标签: c++ templates


【解决方案1】:

创建一个抽象基类。这是一个草图:

class MenuNodeBase {
    std::vector<MenuNodeBase *> forward;
    MenuNodeBase *parent;
    virtual ~MenuNodeBase() = default;
};

template<class T>
class MenuNode : public MenuNodeBase {
    MenuItem<T> t;
};

您可以使用虚函数或dynamic_cast 来访问具体类的功能。

【讨论】:

  • @MooingDuck:如果您在发布后这么快就编辑答案,您将与发帖者发生编辑冲突,就像这里发生的那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
  • 2016-03-31
  • 2018-11-06
  • 2021-06-18
  • 2015-07-26
相关资源
最近更新 更多