【问题标题】:C++ calling a method from another classC++ 调用另一个类的方法
【发布时间】:2014-04-21 21:01:03
【问题描述】:
  • 我有 2 个类及其名为 lexer.cpp 和 lexer.h 的头文件、token.cpp 和 token.h
  • 这些是创建编译器所必需的。目前我还在做词位,划分和阅读令牌。
  • 现在我有一个方法可以读取我从文件中加载的每个字符,例如当它识别出它是一个整数时,它将返回一个 Token(即 token.cpp 中的 Token)

问题:

在 token.cpp 中,我有一个枚举类 Token,其中包含我的编译器可以读取的所有标记(编码将在下面提供)

现在

  1. Lexer.cpp 我必须调用这个类(Token.cpp 中的枚举类 Token)。在 token.h 我刚刚声明了类名
  2. Lexer.h 我写了要在 Lexer.cpp 中使用的方法的名称

但它们会产生一些错误。


错误:


代码:

Lexer.cpp

Token Lexer::getNextToken(char ch)
{
    return Token::tkDigit;
}

lexer.h

#ifndef lexer
#define lexer
#include "token.h"
class Lexer
{
public:

    char ReadChar();
    bool IsDigit (char ch);
    bool IsAlpha (char ch);
    bool IsIdentation (char ch);
    Token getNextToken (char ch);
};

#endif // lexer.h

Token.h

#ifndef token
#define token


enum class Token
{
    tkLetter,
    tkDigit,
    tkPrintable,
    tkType,

    //Literals
    tkBooleanLiteral,
    tkIntegerLiteral,
    tkRealLiteral,
    tkCharLiteral,
    tkStringLiteral,
    tkUnitLiteral,
    tkLiteral,
    tkIndentifier,

    //Operations
    tkMultpicativeOp,
    tkAdditiveOp,
    tkRelationalOp,

    //Params and Calls

    tkActualParams,
    tkFunctionCall,

    //cast and factors
    tkTypeCast,
    tkSubExpression,
    tkUnary,
    tkFactor,

    //Terms and Declarations

    tkTerm,
    tkSimpleExpression,
    tkExpression,
    tkAssignment,
    tkVariableDecl,
    tkFormalParam,
    tkFunctionDecl,

    //Statements
    tkReadStatement,
    tkWriteStatement,
    tkIfStatement,
    tkWhileStatement,
    tkHaltStatement,
    tkStatement,
    tkBlock,
    tkSxl,

};


#endif // token

【问题讨论】:

  • 顺便说一句:enum class Token 的类部分意味着您总是必须将成员限定为例如Token::tkLetter。此时,tk 前缀完全是多余的。
  • 你到底是什么意思?
  • 当您使用enum { Foo }; 声明一个枚举时,您会在当前命名空间中创建一个符号Fooenum class Bar { Foo }; 在命名空间 Bar 内声明 Foo。要访问第一个,您只需写Foo。要访问后者,您必须始终使用命名空间限定它,即Bar::Foo。在您的示例中,枚举既有类又有前缀Token::tkLetter。您应该删除前缀并直接调用它们,例如Token::Letter.

标签: c++ enums token header-files


【解决方案1】:

Lexer.h 中,您使用的是编译器(给定lexer.h 依赖项)一无所知的类型(Token)。

只需包含Token 的声明和include

#ifndef lexer
#define lexer
#include "token.h"

class Lexer

【讨论】:

  • 解决了部分问题,但为什么返回的 tkDigit 仍然没有在这个范围内声明?我的意思是现在包含头文件
  • 因为枚举中的项目是在.cpp文件中定义的,没有被包含进去。将定义移至token.h。根据经验,如果要在另一个类中使用符号,请在 .h 中定义它。
  • 我已经复制了所有内容,但结果还是一样
  • 我的错,我在想老式的 C 枚举,而不是 enum class。因为它是一个类的一部分,Token::tkLetter(正如 kfsone 已经意识到的那样)。
  • 我更改了原始代码中的编码,发布以显示现在的内容。
【解决方案2】:

enum class Token 的定义从 token.cpp 中的 token.h 头文件中移动 替换 ampty 同名枚举的定义并将此标头包含在 lexer.h

正如我所说,将枚举声明从 token.cpp 移到 token.h 中。清楚了吗?

函数 getNextToken 应该是这样的

Token Lexer::getNextToken(char ch)
{
    return Token::tkDigit;
}

【讨论】:

  • 我复制了所有内容,但结果还是一样
  • @odoSerebro 在每个枚举数之前使用限定名,例如 Token::tkLetter
  • 我在 token.h 中包含了枚举的所有定义,并将其导入到 lexer.h ( enum class Token{};) 但是我现在在 Lexer.cpp 中有一个新错误说该方法 Token Lexer::getNextToken 错误:“Token Lexer::getNextToken(char)”的原型与“Lexer”类中的任何内容都不匹配|
  • @DodoSerebro 从类定义中删除这一行:enum class Token{};
  • 我们在 Lexer.cpp 类方法 Token::getNextToken(char ch) 中返回与 tkDigit“未在此范围内声明”相同的错误
猜你喜欢
  • 2016-01-10
  • 2020-10-20
  • 2014-01-31
  • 2013-05-17
  • 2019-08-11
  • 2021-04-02
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多