у меня есть struct Tree
что определено внутри Class Parser
, У меня есть методы, определенные в Parser
что взять Tree
в качестве ввода.
void Parser::InputTree(const Tree& input) {
//uses data from Tree
}
Казалось, все работает нормально. Но тогда мне нужно было использовать Tree
вне класса. Поэтому я решил определить struct Tree
в отдельном заголовке. Я включил этот заголовок в файл заголовка для Parser
, Хотя я не вижу ошибок в заголовочном файле Parser, исходный файл показывает ошибки на моем Eclipse. Говорит, что объявление члена не найдено, указывая на метод InputTree
,
Мой вопрос: во-первых, это правильная стратегия для определения структуры в отдельном заголовке? Во-вторых, что я делаю не так? В-третьих, у меня есть некоторые enum
типы также, что я хочу использовать через классы. Где я могу это определить?
Правильная структура:
parser.h
#ifndef _PARSER_H_
#define _PARSER_H_
#include "tree.h"class Parser {
void InputTree(const Tree& input);
};
#endif /*_PARSER_H_*/
parser.cpp
#include "parser.h"void Parser::InputTree(const Tree& input){
// use data from Tree
}
tree.h
#ifndef _TREE_H_
#define _TREE_H_
struct Tree {
//nodes
};
#endif /*_TREE_H_*/
В том числе parser.h
включает в себя tree.h
и поэтому, struct Tree
доступно в основном блоке компиляции.
Простое эмпирическое правило, которому я обычно следую, — если пользовательский тип данных (т.е. struct, enum и т. Д.) Используется только внутри класса, я в конечном итоге определяю этот тип данных в определении класса.
Но если один и тот же тип требуется использовать в двух или более классах (без каких-либо отношений родитель-потомок), я в конечном итоге определяю тип либо в другом заголовочном файле, либо обычно в пространстве имен (когда типы или связаны каким-либо образом) ,
И да, вы можете использовать несколько таких пространств имен в нескольких заголовочных файлах (для группировки связанных типов), если вы чувствуете необходимость различать их, но я просто покажу более простой пример с использованием одного пространства имен:
/ * MyNamespace.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
/ * Parser.h * /
#ifndef PARSER_H
#define PARSER_H
#include "MyNamespace.h"
class Parser
{
public:
void InputTree(const MyNamespace::Tree& input);
};
#endif
/ * Parser.cpp * /
#include "Parser.h"
void Parser::InputTree(const MyNamespace::Tree& input)
{
}
Да, это правильная стратегия для определения структуры в отдельном заголовочном файле.
То, что вы делаете неправильно, трудно сказать без дополнительной информации, но, вероятно, это связано с включениями, включением охранников или несоответствиями пространства имен.
И, наконец, вы должны объявить перечисления в другом заголовочном файле с соответствующими защитными элементами include.