c++ - 从另一个文件调用一个函数到另一个函数C++

标签 c++ function enums

我有一些头文件,它们承载函数和其他枚举。

所以在 Lexer.h 文件中,我有一个名为 getNextToken() 的函数它返回一个标记,在这个函数中我需要调用一个名为 reservedLookup(string tokenString) 的函数在token.h中找到

reservedWords 是另一个名为 reservedWords.h 的头文件它具有保留字的枚举声明

这个函数在token.h中找到

reservedWords reservedLookup (string tokenString)
{
        for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
        {
            if(tokenString == (rIt->first))
            {
                return rIt->second;
            }

        }
}

在 lexer.h 中,我尝试私下使用它(甚至在公共(public)场合:):

reservedWords reservedLookup(string tokenString);

它编译,但是在函数中时 Token* getNextToken()我用

int tokenType = reservedLookup(strBuffer);

它给我一个错误说明:

obj\Release\main.o:main.cpp:(.text$_ZN5Lexer12getNextTokenEv[__ZN5Lexer12getNextTokenEv]+0x371)||undefined reference to `Lexer::reservedLookup(std::string)'|

我不希望我的编译器将 reservedLookup 读取为 Lexer::reservedLookup(string str) 的一部分但作为 Token::reservedLookup(string str)

有什么办法可以做到吗?


编辑:

token .h

class Token
{
       .....
       .....
public:

    void reservedDeclare ()
    {
         // iterator used for looping through reservedWords

        //Taking care of the Reserved Words first

        reservedMap["function"] =  reservedWords::tkfunction;

        //if - then - else - while - halt
        reservedMap["if"] = reservedWords::tkif;
        reservedMap["else"] = reservedWords::tkelse;
        reservedMap["while"] = reservedWords::tkwhile;
        reservedMap["halt"] = reservedWords::tkhalt;

        //and, or, not, true, else
        reservedMap["and"] = reservedWords::tkand;
        reservedMap["or"] = reservedWords::tkor;
        reservedMap["not"] = reservedWords::tknot;
        reservedMap["true"] = reservedWords::tktrue;
        reservedMap["false"] = reservedWords::tkfalse;

        //sets and read/write
        reservedMap["set"] = reservedWords::tkset;
        reservedMap["let"] = reservedWords::tklet;
        reservedMap["read"] = reservedWords::tkread;
        reservedMap["write"] = reservedWords::tkwrite;

        //variable type
        reservedMap["int"] = reservedWords::tkint;
        reservedMap["char"] = reservedWords::tkchar;
        reservedMap["bool"] = reservedWords::tkbool;
        reservedMap["real"] = reservedWords::tkreal;
        reservedMap["string"] = reservedWords::tkstring;
        reservedMap["unit"] = reservedWords::tkunit;


    }

reservedWords reservedLookup (string tokenString)
{
        for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
        {
            if(tokenString == (rIt->first))
            {
                return rIt->second;
            }

        }
}

reservedWords.h

#ifndef RESERVEDWORDS_H_INCLUDED
#define RESERVEDWORDS_H_INCLUDED

#include <string>
#include <vector> //std::vector
#include <algorithm>    // std::find

using namespace std;

/**
        All the reserved words used by the compiler

*/


    /**
        This file contains all the keywords or reserved words or reserved Symbols used by the compiler
        In the lexer, we will check whether the string we are passing is either a Reserved word
        or it is actually and identifier
    */

    enum reservedWords
    {
        tkfunction,
        tkif,
        tkelse,
        tkwhile,
        tkhalt,

        tkand,
        tkor,
        tknot,
        tktrue,
        tkfalse,

        tkset,
        tklet,
        tkread,
        tkwrite,

        tkint,
        tkchar,
        tkbool,
        tkreal,
        tkstring,
        tkunit,

        tkreservedWord,
        tkidentifier


    };

    #endif // RESERVEDWORDS_H_INCLUDED

Lexer.h部分代码

class Lexer
{
   private:
   string strBuffer ="";//holds the current characters that have been read and waiting to be matched
   int tokenType = 0;
   reservedWords reservedLookup(string tokenString); // THIS DOES NOT WORK. SEES IT AS Lexer::reservedLookup
  ....
  ....
  ...
  ...

  tokenType = reservedLookup(strBuffer); // GIVES ME ERROR BECAUSE OF ABOVE

最佳答案

让我们先看看这部分代码:

class Token
{
  ...
public:
  ...
  reservedWords reservedLookup (string tokenString)
  {       // start of function body
    for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
    {
        if(tokenString == (rIt->first))
        {
            return rIt->second;
        }

    }
  }       // end of function body
  ...
};

在此文件中,您声明了一个函数,其全范围名称为 Token::reservedLookup . (如果您不熟悉术语“完全作用域”,没关系;为了我们的目的,重要的是这是命名此函数的特定方式。)我们可以写成 Token::在此名称的前面,因为此函数是类 Token 的成员.您还通过提供函数体(大括号 {} 中包含的代码)定义了 函数。我在函数体开始和结束的行上添加了注释。

到目前为止,还不错。现在,这个函数是 Token 类的一个普通成员。 ,不是一个“静态”函数,所以为了调用它,你必须首先有一个 Token 类型的对象。 ,然后您可以在该对象上调用此函数,例如在其他函数中编写如下代码:

Token token;
token.reservedDeclare();
reservedWords word = token.reservedLookup("read");

现在是事情变得困惑的部分。你写了这段代码:

class Lexer
{
private:
  ...
  reservedWords reservedLookup(string tokenString);
  ...
};

它的作用是声明一个与第一个函数不同的函数。此函数的全范围名称是 Lexer::reservedLookup .但是,您还没有提供该函数的任何定义(既不在这里,也不明显在其他任何地方)。因此,当您位于 Lexer 的代码内时class 然后你写下这样一行,

tokenType = reservedLookup(strBuffer);

编译器以 C++ 语言规范规定的方式对此进行解释,即这应该是对函数 reservedLookup 的调用。属于出现此调用的同一函数的类。简而言之,它是对 Lexer::reservedLookup 的调用.由于您从未定义该函数,因此不可能生成正确调用该函数的代码,因此您会出错。

所以你可能不想定义 Lexer::reservedLookup根本。如果你不调用 Token::reservedLookup来自类的一个函数Token本身,您可以提供类型为 Token对象这样您就可以调用该函数,就像我在示例中所做的那样。或者,您可能希望将函数的定义设为静态,这样您就可以这样调用它,而不需要 Token 类型的对象。 :

reservedWords word = Token::reservedLookup("read");

然而,为了使这项工作按预期进行,您还必须制作 reservedDeclare静态函数并生成 reservedMap Token 的静态变量,或进行一些其他更改,以便 Token::reservedLookup 使用的数据独立于 Token 类型的特定对象而存在.

您可能还想查看此问题的答案:The Definitive C++ Book Guide and List并阅读推荐的书籍,以帮助更好地理解该语言的术语,以便您可以获得有关您的程序的更好建议。

关于c++ - 从另一个文件调用一个函数到另一个函数C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23690615/

相关文章:

swift - Swift 枚举中的默认参数

c - 查找 C 库中的函数列表

c++ - 使用 auto 推导的 lambda 成员函数模板

c++ - 在范围内振荡一个值

python - 在 fedora 23 上安装 pip install psycopg2 时出错

javascript - 不使用常用方法在JS中对字符串进行重新排序

javascript - setInterval 不调用函数

enums - 使用结构的默认特征作为枚举选项

c# - 防止魔数(Magic Number)和字符串的设计

c++ - 从二维数组 c++ 打印空格而不是整数