Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

struct in separate header file causing problems in C++

I have a struct Tree that is defined inside Class Parser. I have methods defined in Parser that take Tree as input.

void Parser::InputTree(const Tree& input) {
//uses data from Tree
}

Everything seemed to be working fine. But then I needed to use Tree outside the class. So I decided to define struct Tree in a separate header. I included this header in the header file for Parser. While I see no errors in the header file of Parser, the source file shows errors on my Eclipse. Says member declaration not found pointing to method InputTree.

My question is, first off is this the right strategy to define a struct in a separate header? Second, what am I doing wrong? Third, I have some enum types also that I want to use across classes. Where do I define it?

like image 641
user592748 Avatar asked Feb 18 '23 05:02

user592748


2 Answers

Right structure:

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_*/

Including parser.h includes tree.h and hence, struct Tree is available in the main compilation unit.

like image 167
Aniket Inge Avatar answered Mar 03 '23 18:03

Aniket Inge


A simple rule of the thumb I usually follow, is if a custom datatype (i.e. struct, enum, etc.) is used only within a class, I end up defining this datatype within the definition of the class.

But if the same type is required to be used across 2 or more classes (without any parent-child relationship), I end up defining the type either within another header file and usually within a namespace (when the types or related in some fashion).

And yes you could use multiple such namespaces within multiple header files (to group related types), if you feel the need to distinguish them, but I've just show a simpler example using a single namespace:

/* 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)
{

}
like image 23
Tuxdude Avatar answered Mar 03 '23 17:03

Tuxdude