【发布时间】:2015-04-12 22:23:50
【问题描述】:
\\在实现通过对公共基类进行强制转换找到的解决方案时
\\ 与虚拟成员。
\\我发现了有关通用参考的信息,因为这是我创建了一个新问题的另一个问题:
请同时参考这个原始问题。
我想组织不同类型对象的层次树结构。
该解决方案应该在编译时完成它的工作,所以我发现我最多只能使用模板来完成这项工作,而无需任何转换。
在编辑日志中进行了一些尝试并有一些基本缺陷。
我找到了一种方法把它分成两个类
存储所有节点的森林,并给它们两个坐标向量中的索引号
> node 一个模板
,它存储了 T 对象以及与其他节点的关系
我的想法还没有办法在不破坏保护资源管理的唯一指针的情况下访问存储在节点类中的对象的成员函数。
我想知道在访问节点类中的对象时如何确保类型安全。
代码内部可能有错误,我很确定它不会编译,问题是关于概念的。
问题在 cmets 内。
版本 4:
class Forest
{
public:
template<typename T>
{friend class Node<T>;} \\every Node<T> should have access to the forest
Forest();
~Forest();
Forest(const Forest&)=delete; \\does not make any sense to copy or assign the forest to another forest.
Forest operator=(const Forest&)=delete;
int insertroot() \\every tree has a void nullptr seed/root so that the forest does not need to be templatet, returns the treenumber
{ \\implementation
if(this->Nodes.size()==0)
{
std::vector<std::unique_ptr<Node<void> > > h0;
h0.push_back(std::unique_ptr<Node<void>(new Node<void>(nullptr));
this->Nodes.push_back(h0);
}else
{
this->Nodes[0].push_back(std::unique_ptr<Node<void>(new Node<void>(nullptr,this)));
}
return this->Nodes[0].size()-1;
}
Node<void>* getroot(int i) \\ to later allow access to the children and the Objects inside them
{
if(Nodes.size>0){
if((i>0)&(i<Nodes[0].size()))
{
return Nodes[0][i].get();
}
}
private:
std::vector<std::vector<unique_ptr<Node<void> > > nodes; \\is it possible to fill this vector with any Node<T>? its a vector*2 to a unique_ptr to a classpointer with a member pointer to any class. from what i read about templates they create a extra class for every type, so basicly the unique_ptr have a different type and i cannot store different types in a vector without casting?
}
template<typename T>
class Node
{
public:
Node(T n,Forest * Fo) \\ every Node is in the forest and has access to the other nodes and forest information
:object(std::unique_ptr(n)),F(Fo)
{
if(n==nullptr)
{
this->lvl=0;
this->place=F->Node[0].size();
this->parent=-1;
}
}
~Node();
Node(const Node&)=delete;
Node operator=(const Node&)=delete;
T getObject(){return object.get();} \\how does the compiler know the type? see getchild
template<typename C>
{
Node<C> * getchild(int){} \\not yet exsisting implementation of get child[int] how do i teach the compiler what int responds to what type?
\\when i understand templates correct then Node<C> are different Classes for every C??
addChild(C c)
{
Node * n=new Node(c,this->F);
n->parent=this->place;
n->lvl=this->lvl+1
if(F->nodes.size()<=n->lvl)
{
n->place=0;
h0=std::vector<unique_ptr<Node<C>> >;
h0.push_back(unique_ptr<Node<C>(n))
F->Nodes.push_back(h0); \\are vector<uniptrNode<C> > and vector<uniptrNode<void>> compatible?
}else
{
n->place=F->nodes[n->lvl].size();
F->Nodes[n->lvl].push_back(unique_ptr<Node<C> >(n));
}
this->children.push_back(c->place);
}
}
private:
int parent,place,lvl;
std::vector<int> children;
unique_ptr<T> object;
Forest * F;
}
有谁知道实现这样的容器的方法吗? 也许有一些我没有发现的抽象类型,所以我可以添加一个方法类型getnodetype(int)或checknodetype(int,type),我可以用auto nodex = y-> getObject()分配它吗?但是编译器怎么知道nodex有什么方法没有呢?
编辑:我删除了原始帖子,因为 v4 非常接近工作解决方案版本 1-3 应该在编辑日志中
【问题讨论】:
-
你的析构函数是不必要的。存在容器和智能指针,因此您不必手动删除内容。
-
析构函数在那里,以便孩子们在对象之前首先被删除
-
为什么这很重要?在任何情况下,子对象都会在对象之前被删除,因为它出现在类定义中。如果您的班级要求按特定顺序删除内容,您应该在评论中记录下来。
-
你为什么不用
template<class T, class T2, class T3> …?或者使用T1代替普通的T? -
因为我对模板不是很熟悉,而且我不知道模板是否应该是公共成员函数的额外模板。这样,如果 t1 是相同的 void 或 base,编译器会为 addchild 函数生成一个具有不同重载的类?
标签: c++ templates tree unique-ptr type-safety