如何在向量<vector <class * =“”>&gt;中存储类对象并通过引用或值</vector <class>访问并传递它们

时间:2013-09-06 22:55:51

标签: c++ object pointers vector

#ifndef BINARY_TREE_H
#define BINARY_TREE_H

#include<iostream>
#include<vector>

using namespace std;

class Binary_Tree;

static int levelCount=0;

extern vector<vector<Binary_Tree*>> vec;
extern vector<Binary_Tree*> tempVec;

class Binary_Tree
{
  public:
     Binary_Tree()
     {
        childNum=0;
        data=0;
        level=0;
        prev=NULL;
        next[0]=NULL;
        next[1]=NULL;
    };

    Binary_Tree(int d)
    {
         childNum=0;
         data=d;
         level=0;
         prev=NULL;
         next[0]=NULL;
         next[1]=NULL;
         levelCount++;
     }


    void insert_node(int,int,int);

    int get_level();

    int get_childCount();

    friend int set_childNum(Binary_Tree*);

private:
    int childNum;
    int data;
    int level;
    Binary_Tree *prev;
    Binary_Tree *next[2];
};

#endif // BINARY_TREE_H

这是实施文件

#include<iostream>
#include<cmath>
#include "Binary_Tree.h"

using namespace std;



void Binary_Tree::insert_node(int lev, int d, int sib)
{
if(vec.empty())
{
    cout<<"You Have to create Root first";
}

else
{
    if(set_childNum(vec[lev][sib-1])==0)
    {
        cout<<"Child cant be created parent Node already has two childs.";
    }

    else
    {
        childNum=set_childNum(vec[lev][sib-1]);
        data=d;
        level=lev+1;
        prev=vec[lev][sib];
        next[0]=NULL;
        next[1]=NULL;
        tempVec.clear();
        for(int i=0; i<pow(2,(lev+1)); i++)
        {
            if(i==childNum-1)
            {
                tempVec.push_back(this);
            }
            else
            tempVec.push_back(vec[lev][i]);
        }
        vector<vector<Binary_Tree*>>::iterator itr=vec.begin()+(lev+1);
        vec.erase(itr);
        vec.insert(itr,tempVec);
       }
   }
}

int set_childNum(Binary_Tree *lstNdAdr)
{
    if(lstNdAdr->get_childCount()==0)
        return 1;

    else if(lstNdAdr->get_childCount()==1)
        return 2;

    else
      return 0;
}

int Binary_Tree::get_level()
{
    return level;
}

int Binary_Tree::get_childCount()
{
  if(next[0]==NULL)
  {
    return 0;
  }

  else if(next[0]!=NULL && next[1]==NULL)
  {
    return 1;
  }

  else
  {
    return 2;
  }


}

的main.cpp

#include <iostream>
#include<cmath>
#include"Binary_Tree.h"

using namespace std;

vector<vector<Binary_Tree*>> vec;
vector<Binary_Tree*> tempVec;


int main()
{
  Binary_Tree tree;
  here:
  cout<<"Enter your Choice:1.Create Root Of Tree\n"
      <<"2.Insert node\n"<<endl;

  int choice;
  cin>>choice;

  switch(choice)
  {
    case 1:
      {
        int d;
        cout<<"Enter Data to insert: ";
        cin>>d;

         Binary_Tree treeDummy(d);

         tree=treeDummy;

         tempVec.push_back(&tree);

         vec.push_back(tempVec);
       }

     break;

    case 2:
    {
        int lev;
        int sibbling;
        int d;
        cout<<"Enter at which level and data and parent's sibling-no.: ";
        cin>>lev;
        cin>>d;
        cin>>sibbling;

        if(sibbling>pow(2,lev))
            cout<<"Illegal Sibbling Number."<<endl;
        else
            tree.insert_node(lev,d,sibbling);

    }
    break;
}
int x;
cin>>x;
if(x==5)
{
    cout<<endl<<endl;
    goto here;

}

  return 0;
}

在上面的代码中我试图创建一个二进制树类型结构,可以动态地操作和遍历,任何节点都可以插入,并且可以在运行时删除(虽然它不完整,因为我遇到了问题)。在推回tempVec向量时,代码会产生分段错误,而且我也怀疑传递存储在vetcor中的对象&gt; vec到实现中的函数(我是Stl的新手,第一次处理包含类类型指针的向量向量)

2 个答案:

答案 0 :(得分:1)

仅当i设置为1时,才会填充嵌套向量的条目。但无论如何,您都尝试访问其元素[0][0]i不是1时,您的界限不受限制。

答案 1 :(得分:1)

您的代码中存在许多问题,并且与糟糕的样式和格式相结合使调试变得不那么有趣。

   Binary_Tree treeDummy(d);
   tree = treeDummy;

   tempVec.push_back(&tree);

我不确定你在这里尝试做什么,但上面看起来不对。您正在将treeDummy的数据复制到树上。您将丢失指向子节点树的链接。之后,您将同一个树实例推送到临时向量中。这意味着向量中的所有元素最终都指向tree中的局部变量main。因此,即使没有发生段错误,您也会遇到别名问题,因为它们都引用相同的tree对象,而不是单独的BinaryTree实例。

  vector< vector<Binary_Tree*> >::iterator itr=vec.begin()+(lev+1);
  vec.erase(itr);
  vec.insert(itr,tempVec);

BinaryTree::insert_node执行未定义的行为后,您的erase正在使用无效的迭代器。

  childNum = set_childNum(vec[lev][sib-1]);
  // ...
  prev = vec[lev][sib];

以上内容可以访问向量中的越界索引。例如。您推送tempVec只包含1个元素,然后使用insert_node = 1来调用sib

 // ...
 if(x == 5)
 {
   cout<<endl<<endl;
   goto here;
 }

此处也完全没有goto的使用,应该使用传统的while循环来替换condition != 5

然而,程序中的更高级别问题是其设计中没有明确的约束和不变量。每个功能需要有哪些假设和先决条件?为什么在类本身应该处理它时使用向量来保存BinaryTree个节点。你应该首先整理整体设计,否则你只会在其他错误出现的时候玩w鼹鼠。