单独的头文件中的结构导致C++中的问题

单独的头文件中的结构导致C++中的问题,c++,struct,enums,function-declaration,C++,Struct,Enums,Function Declaration,我有一个在类解析器中定义的结构树。我在解析器中定义了将树作为输入的方法 void Parser::InputTree(const Tree& input) { //uses data from Tree } 一切似乎都很顺利。但是我需要在课外使用Tree。所以我决定在一个单独的头中定义结构树。我在解析器的头文件中包含了这个头文件。虽然我在解析器的头文件中没有看到错误,但源文件在我的Eclipse上显示了错误。表示未找到指向方法InputTree的成员声明 我的问题是,首先,这是在单独的

我有一个在类解析器中定义的结构树。我在解析器中定义了将树作为输入的方法

void Parser::InputTree(const Tree& input) {
//uses data from Tree
}
一切似乎都很顺利。但是我需要在课外使用Tree。所以我决定在一个单独的头中定义结构树。我在解析器的头文件中包含了这个头文件。虽然我在解析器的头文件中没有看到错误,但源文件在我的Eclipse上显示了错误。表示未找到指向方法InputTree的成员声明

我的问题是,首先,这是在单独的头中定义结构的正确策略吗?第二,我做错了什么?第三,我还有一些枚举类型,我想跨类使用它们。我在哪里定义它?

正确的结构:

解析器.h

parser.cpp


include parser.h包括tree.h,因此,结构树在主编译单元中可用。

是的,在单独的头文件中定义结构是正确的策略

如果没有更多的输入,很难说您做错了什么,但这可能与包含、包含保护或命名空间不匹配有关


最后,您应该在另一个头文件中声明枚举,并使用适当的include-guard。

我通常遵循的一个简单经验法则是,如果自定义数据类型(如struct、enum等)仅在类中使用,我最终会在类的定义中定义此数据类型

但是,如果需要在2个或更多没有任何父子关系的类中使用相同的类型,那么我最终会在另一个头文件中定义该类型,并且通常在名称空间中定义该类型,当这些类型或类型以某种方式关联时

是的,如果您觉得有必要区分相关类型,您可以在多个头文件中使用多个这样的名称空间来对相关类型进行分组,但我只展示了一个使用单个名称空间的简单示例:

/*MyNamespace.h*/

/*解析器.h*/

/*Parser.cpp*/


抱歉,我忘了添加我有一个类的模板参数。当我在类外部定义结构时,我使用了void Parser::inputreeconst Tree&input{}。但是,谢谢你这么详细的解释。- 1,TyeErthHyg和Pa SysRyHyg被保留给C++ C++实现。同样,标准保留了带有两个前导下划线的宏,用于实现名称篡改。因此,你的包含守护宏应该是TeeEyHy.MyNyNeSePaCeEthHyg和PySeruHyl是保留给C++实现的标识符。@ RabSO3.3.14,你能提供一些参考来支持这个事实吗?每个包含双下划线或以下划线开头,后跟大写字母2.12的名称都保留给实现使用。我知道双下划线,但不知道另一个。好消息:
#ifndef _PARSER_H_
#define _PARSER_H_
#include "tree.h"
class Parser {
   void InputTree(const Tree& input);
};

#endif /*_PARSER_H_*/
#include "parser.h"
void Parser::InputTree(const Tree& input){
 // use data from Tree
}
#ifndef _TREE_H_
#define _TREE_H_

struct Tree {
   //nodes
};
#endif /*_TREE_H_*/
#ifndef MY_NAMESPACE_H
#define MY_NAMESPACE_H

namespace MyNamespace {
    struct Tree {
        int a;
        char b;
    };

    enum SomeEnum {
        VALUE_0 = 0,
        VALUE_1 = 1,
        VALUE_2 = 2
    };
}

#endif
#ifndef PARSER_H
#define PARSER_H

#include "MyNamespace.h"

class Parser
{
public:
    void InputTree(const MyNamespace::Tree& input);
};

#endif
#include "Parser.h"

void Parser::InputTree(const MyNamespace::Tree& input)
{

}