2013-03-10 85 views
4

我有一個struct TreeClass Parser內定義。我有Parser中定義的方法,其中Tree作爲輸入。結構在單獨的頭文件導致C++中的問題

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

一切似乎工作正常。但之後我需要在課外使用Tree。所以我決定在一個單獨的頭文件中定義struct Tree。我將這個頭文件包含在Parser的頭文件中。雖然我在Parser的頭文件中看不到任何錯誤,但源文件在我的Eclipse上顯示錯誤。說沒有發現成員聲明指向方法InputTree

我的問題是,首先是這是一個正確的策略來定義一個單獨的頭結構?其次,我做錯了什麼?第三,我也有一些enum類型,我想跨類使用。我在哪裏定義它?

回答

3

右結構:

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是在主編譯單元可用。

+0

對不起,我忘了補充一點,我有一個模板參數爲班級。當我在類之外定義結構時,我使用了'void Parser :: InputTree(const Tree &input){}'。不過謝謝你這樣詳細解釋。 – user592748 2013-03-10 21:05:21

+1

-1,'_TREE_H_'和'_PARSER_H_'保留給C++實現。 – 2013-03-11 00:41:26

+0

@ robson3.14吧? – 2013-03-11 06:24:01

2

是的,在單獨的頭文件中定義結構是一個正確的策略。

如果沒有更多的輸入,你做錯了很難說 - 但它可能與include,include-guard或命名空間不匹配有關。

最後,你應該在另一個頭文件中聲明枚舉,並使用適當的包含守護進程。

3

我通常遵循的一個簡單的規則是,如果僅在類中使用自定義數據類型(即結構體,枚舉等),我最終會在類的定義中定義此數據類型。

但是,如果需要跨2個或更多的類(沒有任何父 - 子關係)使用相同的類型,我最終在另一個頭文件中定義類型,通常在命名空間內(類型或相關以某種方式)。

是的,你可以使用中的多個頭文件的多個這樣的命名空間(將相關類型),如果你覺得有必要區分它們,但我一直在使用一個命名空間只是顯示一個簡單的例子:

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

} 
+0

'_MY_NAMESPACE_H_'和'_PARSER_H_'是保留給C++實現的標識符。 – 2013-03-11 00:44:55

+0

@ robson3.14 - 你能否提供一些參考來回避這個事實? – Tuxdude 2013-03-11 00:53:17

+2

17.6.4.3.2 [global.names] 包含雙下劃線_ _的每個名稱或以下劃線開頭且後面帶有大寫字母 的字母(2.12)保留給實施用於任何用途。 – 2013-03-11 01:00:10