tags:

views:

96

answers:

4

I asked a similar question in this posting and learned from the replys but

I still can't get it to work.

test_vector.h

    #include <vector>
    class Node
    {
    public:
     std::vector<Node*>& node_dict;
     int depth;
     char* cargo;
     Node* left;
     Node* right;
     Node( int a_depth, std::vector<Node*>& a_dict);
     ~Node();
    };

    class Tree
    {
    public:
     std::vector<Node*>tree_dict;
     Node* root;
     Tree();
     Tree(const Tree &original);
    };

test_vector.cpp

    #include "test_vector.h"

    using namespace std;
    typedef std::vector<Node*>Dictionary;//This seems like a good idea.
    typedef std::vector<Tree*>Population;
    Population pop;
    int Tree_depth = 3;

    Node::Node( int a_depth, std::vector<Node*>&a_dict):node_dict(a_dict), depth(a_depth)
    {
     if (depth <= 0)
     {
      cargo = "leaf_Node";
      left = 0;
      right = 0;
      node_dict.push_back(this);
      return;
     }
     else;
     {
      cargo = "Tree_Node";
      node_dict.push_back(this);
      depth--;
      left = new Node(depth, node_dict);
      right = new Node(depth, node_dict);  
     }
     return;
    };
    Node::~Node()
    {
     delete left;
     delete right;
    };

    Tree::Tree():tree_dict(NULL)
    {
     ****tree_dict = new Dictionary;****
     root = new Node(Tree_depth, tree_dict);
    };
    //copy constructor
    Tree::Tree(const Tree &original):tree_dict(NULL) 
    {
     root = NULL;
    root = new Node (*(original.root));
    };


    int main()
    {
     for (int i = 0;i <= 3; i++)
     {
     pop.push_back(new Tree());
     }
     return 0;
    }

The line with the asterisks doesn't work. "tree_dict = new Dictionary"

the error is:

"no operator "=" matches these operands.

What I'm trying to do is create a new vector of Node*s whenever a new Tree is

instantiated. Pass a reference to the new vector (tree_dict) to the Node

constructor, which will pass that reference to each new instance of Node

(Node* left and Node* right) which can push_back a pointer to themselves before

passing the reference on to their child Nodes.

So each Tree.tree_dict is a single vector containing pointers to each Node* in

the tree. I need some help please.

A: 

If you new a type in C++, you get a pointer to a heap allocated object. If you want to allocate it in place, write the constructor without the new keyword.

jdv
I'd love to allocate it in place, but I need to instatiate a new vector each time the Tree constructor is called.
Peter Stewart
@Peter Then you need to pass it as *tree_dict and you need to make sure it is `delete`d somewhere.
rlduffy
+2  A: 
tree_dict = new Dictionary;

That says "Allocate a new Dictionary object on the heap, and store a pointer to it in tree_dict". Unfortunately, tree_dict is not a pointer.

tree_dict = Dictionary();

This says "Create a new Dictionary object, and copy it into tree_dict."

James Curran
"tree_dict = Dictionary();" is a no-op since it is being used at the beginning of the Tree constructor (the vector will be initialized automatically and doesn't require "new"). He could fix (that part of) the program by simply deleting that line. He also needs to delete the tree_dict(NULL) initialization just above that. Unless, maybe he DID intend for tree_dict to be a pointer, in which case he needs to modify the declaration of tree_dict to be a pointer.
nobar
@nobar: yes, that works, thanks
Peter Stewart
A: 

That should simply be:

Tree::Tree() : tree_dict() // you can also omit the explicit initialization
{
    // no assignment to tree_dict needed, its already initialized
    root = new Node(Tree_depth, tree_dict);
};

tree_dict is not a pointer, you are storing the vector by value.

Note that as posted you are at least leaking the memory for root as Tree doesn't have a destructor which deletes it. Alternatively you can use smart pointers like std::auto_ptr which deletes it automatically for you and helps making your code exception-safe:

class Tree {
public:
    std::vector<Node*> tree_dict;
    std::auto_ptr<Node> root;
    Tree() : tree_dict(), root(new Node(Tree_depth, tree_dict)) {}
    // ...
};

Same goes for the tree_dict which would be better off as a vector of e.g. Boosts or TR1 shared_ptr or something like Boosts ptr_vector.

Georg Fritzsche
I've seen Boosts mentioned a lot. I guess I'll have to learn it. Thanks for the other pointers as well.
Peter Stewart
+2  A: 

Holy hell there's a lot wrong with your code. You should probably go through a begging C++ book to learn the basics because even if your code was compilable, it's very very poorly implemented. The one thing I have to point out that no one seems to have mentioned is the

declaration of std::vector<Node*>& node_dict;

You can't declare a reference like that. A reference HAS to be an assignment. You're saying node_dict is a reference to a a std::vector<Node*> object, but not telling it what it's referencing. If this compiles then your compiler is pulling out the & symbol instead of throwing an error like ti should.

As for the poorness of your code, why are you even declaring node_dict as a class variable? You assign it a value in your constructor, but then don't use it outside of your constructor. There's no reason it should be a class variable.

Falmarri
Gosh, that's why I'm asking questions here. Thanks for those two corrections.(of course of course i shoulda seen that!)
Peter Stewart
Sorry I don't mean to be rude. It's just we see a ton of questions here that are essentially C# source written in C++. Or people who have written a few hello world programs trying to implement complex multi-class programs who don't understand object composition and asking why they have syntax errors.
Falmarri