【问题标题】:Error: expected constructor, destructor, or type conversion before '*' token|错误:“*”标记之前的预期构造函数、析构函数或类型转换|
【发布时间】:2016-06-26 02:15:46
【问题描述】:

我正在尝试实现二叉搜索树。代码不完整,但我还是构建了它,看看我会得到什么可能的错误。 这是它的代码:

BST.h
class BST {

    public:
    struct node
    {
        //All nodes must be able to point to left and right
        int key;  //All nodes can hold a key value
        node* left; //All nodes have a left pointer
        node* right;//All nodes have a right pointer
    };

    node* root; //References the very top of the tree

    public:
        BST(); //Constructor that initializes each time instance is called
        node* CreateLeaf(int key);

};
BST.cpp
#include<iostream>
#include<cstdlib>

#include "BST.h"
using namespace std;

BST::BST()
{
    root = NULL;
}

node* BST::CreateLeaf(int key) //Causing errors
{
    node* n = new node;
    n->key = key;
    n->left = NULL;
    n->right = NULL;
    return n;
}
main.cpp
#include <iostream>
#include <cstdlib>

#include "BST.cpp"


using namespace std;

int main()
{

return 0;
}

这给出了错误: 错误:“*”标记之前的预期构造函数、析构函数或类型转换

在 BST.cpp 文件中,如果我将 CreateLeaf() 函数声明为:

typedef node* BST::CreateLeaf(int key)

错误变为: 错误:“*”标记之前的预期初始化程序

现在,根据常识,由于我在类之外声明 CreateLeaf 函数,所以我这样做:

BST::node* BST::CreateLeaf(int key)

现在错误变为: 错误:在 BST 函数中:`BST::BST()' 的多个定义

我在 Windows 10 上使用 CodeBlocks IDE。

编辑: 我删除了 .cpp 文件并在头文件中声明了所有函数(并在主函数中包含了头文件)。现在正在编译。但是,如果有人可以让我知道为什么会首先发生错误,那就太好了。

【问题讨论】:

  • 错误位置是什么?
  • 您不包含 .cpp 文件;这不是它应该如何工作的。
  • youtube.com/… 我使用这个视频作为参考。它适用于他,为什么不适用于我?
  • "为什么不用 "BST.h" 而不是包含 "BST.cpp"。很多人告诉我包含你的源文件是一种不好的做法。"跨度>

标签: c++ binary-tree codeblocks


【解决方案1】:

在声明中

node* BST::CreateLeaf(int key)

…编译器不知道名称node,因为它是在BST 类中定义的,并且在该类之外使用。

一个简单的解决方法是使用更新的尾随返回类型语法:

auto BST::CreateLeaf(int key)
    -> node*

这里编译器知道声明属于BST类,在它遇到node的点。

或者,您可以限定名称,

BST::node* BST::CreateLeaf(int key)

...但这会很快变得丑陋,尤其是使用模板代码。


在其他新闻中,

#include "BST.cpp"

... 在文件 main.cpp 中是不好的做法。一个实际原因是,在 IDE 项目中,这可能会导致代码被编译两次:一次编译 BST.cpp,另一次编译包含在 main.cpp 中的相同代码。

而只是单独编译BST.cpp

或者,将其设计为头文件模块(主要涉及将函数声明为inline)。

【讨论】:

  • 使用 auto 会产生另一个错误。它说它希望在“*”标记之前有一个初始化程序。
  • 我删除了 BST.cpp 文件。我在 BST.h 文件的类中声明了所有类函数。现在正在编译成功...
  • 请务必将您移动到头文件的所有函数实现标记为inline(否则当头文件用于两个或更多翻译单元时,您可能会收到链接器错误)。关于“自动生成另一个错误”,我无法重现。可能是笔误。
  • 不使用#import 代替#include 解决头文件被包含在多个位置的问题吗?它首先检查它是否存在,如果不存在则包含。
  • @SaunvedMutalik: #import 可以是 (1) 一个用于处理 COM 模块的 Microsoft 语言扩展,或者 (2) 如果我没记错的话,一个提议的 C++ 模块语法,尚未标准化,但已通过实验实现通过 Visual C++。可能在(2)的意义上它会像你说的那样大致工作。但是我没用过所以不知道,抱歉。
【解决方案2】:

在类声明之外,您需要将作用域前缀为node

   BST::node* BST::CreateLeaf(int key) { 
// ^^^^^ ...
   }

您也不应该包含.cpp 文件。包含头文件,分别编译链接.cpp文件。

【讨论】:

  • 查看我的最后几行问题。这样做会产生错误:error:multiple definition of `BST::BST()'|
  • 这当然是一个(尴尬的)解决方案,但没有“需要”这样做。
  • @SaunvedMutalik 你还没有告诉我们错误的位置。
  • 错误位置是什么意思?错误发生在 BST.cpp 文件中 CreateLeaf() 的声明处。
猜你喜欢
  • 2018-12-04
  • 2016-03-14
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多