0

There is a weird syntax error in this code. I don't understand it or any of the errors.

#pragma once
#include <iostream>
class Tree {
public:
    Node* root;
    void InputTree() {
        int n, father;
        int nd;
        int child;
        char dir;
        std::cin >> n;
        int** tree = new int* [n];
        for (int i = 0; i < n; i++) {
            std::cin >> nd;
            tree[i] = new int[3];
            tree[i][0] = nd;
            tree[i][1] = -1;
            tree[i][2] = -1;
        }

        for (int i = 0; i < n - 1; i++) {
            std::cin >> father >> child >> dir;
            if (dir == 'L')
                tree[father][1] = child;
            else
                tree[father][2] = child;
        }
        Initialize(tree, 0);
    }
private:
    void Initialize(int** tree, int headIndex) {
        if (headIndex != -1) {
            root->value = tree[headIndex][0];
            root->right_tree->Initialize(tree, tree[headIndex][2]);
            root->left_tree->Initialize(tree, tree[headIndex][1]);
        }
    }
};
class Node {
public:
    int value;
    Tree* left_tree;
    Tree* right_tree;
};

This is the build output of Visual Studio:

Build started...
1>------ Build started: Project: CppMainProject, Configuration: Debug Win32 ------
1>CppMainProject.cpp
1>tstream.h(5,6): error C2143: syntax error: missing ';' before '*'
1>tstream.h(5,6): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>tstream.h(5,12): error C2238: unexpected token(s) preceding ';'
1>tstream.h(33,4): error C2065: 'root': undeclared identifier
1>tstream.h(34,4): error C2065: 'root': undeclared identifier
1>tstream.h(35,4): error C2065: 'root': undeclared identifier
1>Done building project "CppMainProject.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • I'll bet you could remove 95% of that code and still get the error. – Pete Becker Dec 03 '21 at 20:44
  • `Node` has to be moved above `Tree` – HolyBlackCat Dec 03 '21 at 20:49
  • It's usually worth [trying another compiler](https://gcc.godbolt.org/z/r33a6dEYf) when you get an error you don't understand. Different compilers do better in different situations. – chris Dec 03 '21 at 20:50
  • And then `Tree` has to be forward-declared (`class Tree;`) before `Node`: you're using class names before they are known to the compiler. – sigma Dec 03 '21 at 20:50

3 Answers3

2

In lines like root->value = tree[headIndex][0];, you are trying to use the Node class before you have told the compiler what that class is. You can declare variables as pointers to classes before their full definition (but you need a forward declaration of the class to do so) but you can't dereference such pointers until after the full class definition has been provided.

In your code, you can move the definition of the Node class to before the Tree class; but then, as that uses Tree pointers, you have to provide a forward declaration that Tree is a class.

#pragma once
#include <iostream>

class Tree; // Forward declaration that this is a class...

class Node {
public:
    int value;
    Tree* left_tree; // ... so we can now declare pointers to "Tree"
    Tree* right_tree;
};

class Tree {
public:
    Node* root; // We can declare a pointer 
    void InputTree()
    {
    // ... and then the rest of your code as is ...

Some worthwhile reading: When can I use a forward declaration?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 1
    This is the best answer so far. It requires fewer changes to the code than the other two suggestions. – TonyK Dec 03 '21 at 22:36
  • Thanks, but when i did it it says 'Access violance writing' or something like the line `root->value = tree[headIndex][0]` – Moataz Craft Dec 05 '21 at 20:51
  • @MoatazCraft That's likely because you haven't properly initialized your `Node` member. But that's really a separate question, and you haven't shown the code where you actually use the classes, so I can't really offer anything more, here. Maybe think about how you're setting up your `Tree` and `Node` allocations and, if you still have issues, ask a new question. – Adrian Mole Dec 05 '21 at 21:12
  • ... most probably, though, you'll want a constructor for your `Tree` class that allocates something for the `root` member to point to ... you can't dereference an uninitialized (or null) pointer. – Adrian Mole Dec 05 '21 at 21:15
0

Node is still not defined when you declare root. Try to move Node Class inside Tree class, and I recommend you changing it to struct as folowing:

#pragma once
#include <iostream>
class Tree {
public:

    void InputTree() {
        int n, father;
        int nd;
        int child;
        char dir;
        std::cin >> n;
        int** tree = new int* [n];
        for (int i = 0; i < n; i++) {
            std::cin >> nd;
            tree[i] = new int[3];
            tree[i][0] = nd;
            tree[i][1] = -1;
            tree[i][2] = -1;
        }

        for (int i = 0; i < n - 1; i++) {
            std::cin >> father >> child >> dir;
            if (dir == 'L')
                tree[father][1] = child;
            else
                tree[father][2] = child;
        }
        Initialize(tree, 0);
    }
private:
    struct Node {
        int value;
        Tree* left_tree;
        Tree* right_tree;
    };
    Node* root;
    void Initialize(int** tree, int headIndex) {
        if (headIndex != -1) {
            root->value = tree[headIndex][0];
            root->right_tree->Initialize(tree, tree[headIndex][2]);
            root->left_tree->Initialize(tree, tree[headIndex][1]);
        }
    }
};
0

If you want it to all be in one file, forward declare Node and move the definition of Tree::Initialize(...) after the definition of Node. Or just forward declare Node and use the typical .h file / .cpp file split.

Single file versions goes like this:

class Node;  // <= this is a forward declaration...

class Tree {
public:
    Node* root;
    void InputTree() {
        // ....
    }
private:
    void Initialize(int** tree, int headIndex);
};

class Node {
public:
    int value;
    Tree* left_tree;
    Tree* right_tree;
};

void Tree::Initialize(int** tree, int headIndex)
{
    // ...
}
jwezorek
  • 8,592
  • 1
  • 29
  • 46