【问题标题】:Weird syntax error in a simple code in C++C++ 中的简单代码中出现奇怪的语法错误
【发布时间】:2022-01-10 04:24:12
【问题描述】:

这段代码中有一个奇怪的语法错误。我不明白它或任何错误。

#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;
};

这是 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 ==========

【问题讨论】:

  • 我敢打赌,你可以删除 95% 的代码,但仍然会出现错误。
  • Node 必须移到Tree上方
  • 当您遇到不理解的错误时,通常值得trying another compiler。不同的编译器在不同的情况下表现更好。
  • 然后Tree 必须在Node 之前被前向声明(class Tree;):你在使用类名之前编译器知道它们。

标签: c++ visual-studio


【解决方案1】:

Node 在声明root 时仍未定义。尝试将 Node Class 移动到 Tree 类中,我建议您将其更改为 struct 如下:

#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]);
        }
    }
};

【讨论】:

    【解决方案2】:

    如果您希望它们都在一个文件中,请转发声明 Node 并将 Tree::Initialize(...) 的定义移动到 Node 的定义之后。或者只是转发声明Node 并使用典型的.h 文件/.cpp 文件拆分。

    单个文件版本如下:

    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)
    {
        // ...
    }
    

    【讨论】:

      【解决方案3】:

      在像root-&gt;value = tree[headIndex][0]; 这样的行中,您在告诉编译器该类是什么之前尝试使用Node 类。您可以在它们的完整定义之前将变量声明为指向类的指针(但您需要forward declaration of the class 这样做),但在完整定义之前不能取消引用此类指针已提供类定义。

      在您的代码中,您可以将Node 类的定义移动到之前 Tree 类;但是,由于它使用 Tree 指针,您必须提供 Tree 是一个类的前向声明。

      #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 ...
      

      一些值得一读的:When can I use a forward declaration?

      【讨论】:

      • 这是迄今为止最好的答案。与其他两个建议相比,它需要的代码更改更少。
      • 谢谢,但是当我这样做时,它会显示“访问暴力写作”或类似root-&gt;value = tree[headIndex][0]
      • @MoatazCraft 这可能是因为您没有正确初始化您的Node 成员。但这确实是一个单独的问题,并且您还没有显示实际使用这些类的代码,因此我在这里无法提供更多信息。不妨想想您是如何设置 TreeNode 分配的,如果您仍有问题,请提出新问题。
      • ...不过,您很可能需要一个 Tree 类的构造函数,该构造函数为 root 成员分配一些指向...您不能取消引用未初始化的(或空)指针。
      猜你喜欢
      • 1970-01-01
      • 2013-11-01
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多