【问题标题】:Expecting function body despite it being provided尽管提供了功能体,但仍期待它
【发布时间】:2021-12-30 09:27:33
【问题描述】:

我有一个名为Node 的基类,它定义了两个函数:indenttoString。前者将被所有派生类使用而不被覆盖,但后者将在派生类中被覆盖。

Node.hpp

#ifndef NODE_H
#define NODE_H

#include <string>
#include <vector>
#include <memory>

class Node {
    public:
        virtual std::string toString(int level) const {};
        std::string indent(int level);
};

#endif

Node.cpp

#include "Node.hpp"

std::string Node::indent(int level) {
    std::string indt;
    for(int i = 0; i < level; i++) {
        indt += "\t";
    }
    return indt;
}

我有一个派生类 FunctionNode,它想要覆盖 node.hpp 中的 toString

FunctionNode.hpp

#ifndef FUNCTION_NODE_H
#define FUNCTION_NODE_H

#include "TypeNode.hpp"
#include "ParamsNode.hpp"
#include "BlockNode.hpp"
#include "DeclarationNode.hpp"

class FunctionNode : public DeclarationNode {
    std::shared_ptr<TypeNode> type;
    std::string name;
    std::shared_ptr<ParamsNode> paramList;
    std::shared_ptr<BlockNode> block;

    public:
        FunctionNode(std::shared_ptr<TypeNode> type,
                const std::string &name,
                std::shared_ptr<ParamsNode> paramList,
                std::shared_ptr<BlockNode> block)
            : type(std::move(type)), name(name),
                paramList(std::move(paramList)), block(std::move(block)) {}
};

#endif

请注意,DeclarationNode 派生自 Node

函数节点.cpp

#include "FunctionNode.hpp"

std::string FunctionNode::toString(int level) const override {
    std::string indt = indent(level);
    std::string s = indt + "FunctionNode\n"; 
    s += type->toString(level + 1);
    s += indt + "\t" + name + "\n";
    s += paramList->toString(level + 1);
    s += block->toString(level + 1);
    return s;
}

当我尝试使用 Makefile 中的以下行将 FunctionNode.cpp 编译为对象时。

FunctionNode.o: FunctionNode.cpp FunctionNode.hpp TypeNode.hpp ParamsNode.hpp BlockNode.hpp

我收到以下错误。

FunctionNode.cpp:3:55: error: expected function body after function declarator
std::string FunctionNode::toString(int level) const override {
                                                      ^

但是我已经提供了函数体。如何解决此错误?

【问题讨论】:

  • 我在FunctionNode.hppFunctionNode 的定义中没有看到FunctionNode::toString 的声明。
  • 您为哪个 C++ 版本编译?另外,所有这些代码真的有必要吗(IOW,是minimal reproducible example)吗?
  • 我认为既然我重写了 toString 我不必再次声明它。 @内森皮尔森
  • 不,您仍然需要声明要覆盖的虚函数。
  • 这并没有解决问题,但是std::string 知道如何处理多个重复字符,因此indent 函数可以简单得多:std::string Node::indent(int level) { std::string indt(level, '\t'); return indt; }。此外,由于它不使用类Node 中的任何数据,它应该是一个静态 成员函数。

标签: c++ function class inheritance


【解决方案1】:

您的程序没有Node::toString 方法的return 语句。除此之外似乎没有任何其他错误,除了

致命错误:TypeNode.hpp:没有这样的文件或目录

因为您没有在原始问题中提供TypeNode.hpp

程序没有有你提到的错误,可以看到here。如果您可以提供minimal reproducible example 并编辑您的问题,那就太好了。注意FunctionNode::toString 也已在上述链接的FunctionNode 类中声明。

【讨论】:

    【解决方案2】:

    要覆盖子类中的函数,您需要在类定义中编写声明。覆盖说明符只会出现在头文件中。

    头文件

    class FunctionNode : public DeclarationNode {
      FunctionNode(...) { ... }
      std::string toString(int level) const override; 
    };
    

    源文件

    #include "FunctionNode.hpp"
    
    std::string FunctionNode::toString(int level) const {
      ...
    }
    

    【讨论】:

    • 谢谢。它解决了我的问题,但现在它说:成员函数“indent”的“this”参数具有类型“const FunctionNode”,但函数未标记为 const std::string indt = indent(level);
    • 当然。 toString() 是一个 const 方法。您不能从 const 方法调用非 const 成员函数,例如 indent
    猜你喜欢
    • 2021-02-08
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2015-12-10
    • 1970-01-01
    • 2014-03-29
    • 2019-09-03
    相关资源
    最近更新 更多