将另一个文件中的函数调用到另一个函数C ++中

时间:2014-05-16 00:00:57

标签: c++ function enums

我有一些主机功能和其他枚举的头文件。

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

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中我尝试私下使用它(甚至在公共场合:):

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的PARTIAL代码

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

1 个答案:

答案 0 :(得分:3)

让我们先看一下代码的这一部分:

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:: name,因为此函数是类Token的成员。您还通过提供函数体(括号{}中包含的代码)来定义函数。我在函数体开始和结束的行上添加了注释。

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

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

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

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

这样做是为了从第一个声明不同的函数。此函数的完全范围名称为Lexer::reservedLookup。但是,您没有提供该函数的任何定义(既不在这里,也不在任何其他地方)。所以当你在Lexer类的代码中并且你写了一行这样的行时,

tokenType = reservedLookup(strBuffer);

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

所以你可能根本不想定义Lexer::reservedLookup。如果您未从类Token::reservedLookup本身的某个功能中调用Token,则可以提供类型为Token对象,以便您可以拨打电话功能,正如我在我的例子中所做的那样。或者,您可能希望将函数的定义设置为static,以便可以通过这种方式调用它,而无需Token类型的对象:

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

但是,为了使这项工作符合要求,您还必须使reservedDeclare成为静态函数,并使reservedMap成为Token的静态变量,或进行其他更改以便Token::reservedLookup使用的数据独立于Token类型的特定对象。

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