2012-02-08 6 views
1

私はJavaの開発者ですが、最近C++を習得しなければならず、いくつかのことについて混乱しています。私がしたいのは、作成しているスイート全体で一定の#define変数のリストを持つ 'グローバル'ヘッダーファイルを作成することです。私は私がそれを必要とするヘッダファイルが含まれていませんが、何も存在している...私の問題は、私はこれらにアクセスすることができないということですcppファイルのないヘッダファイルの使用方法

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

#define SM_START   1001; 
#define SM_PAUSE   1002; 
#define SM_STOP    1003; 
#define SM_SAVE    1004; 
#define SM_DISCARD   1005; 
#define SM_SETUP   1007; 


#endif // CONSTANTS_H 

を私は、ヘッダファイルを作成し、私はいくつかの変数

を追加しました私の内部の定数にアクセスする方法。 Do I に.cppファイルがありますか?定数変数にアクセスする方法はありますか?

+1

以下の素敵なコメントに加えて、避けることができる場合は単純な数値定数に#defineを使用しないでください。 'const int SM_START = 1001;'などとすると、同じ効果が得られ、エラーメッセージがもっと簡単になる。 –

答えて

4

最初に:#defineの最後にセミコロンを挿入しないでください。 #defineはプリプロセッサディレクティブです。つまり、定義された名前とコンテンツのテキスト置換が基本的に行われます。だからint a = SM_STOP + 1;のようなことをすれば、コードでint a = 1003; + 1;に前処理されます。これはあなたが望むものではありません。

2番目:ヘッダーは一般的にコンパイルされませんが、*.cppファイルやその他のヘッダーに含めるためにのみ使用されます(#includeはもう一度テキスト置換されます)。したがって、あなたは.cppファイルをどこかに持っている必要があります(正確にはまず最初に別の拡張子を選ぶことができます.2番目にコンパイル単位としてヘッダを与えることもできますが、少なくともあなたが知るまで何をしているの)。しかし、あなたの定数に.cppファイルを持つ必要はありません。#includeあなたの定数を使用したいファイルにヘッダを入れてください。

3番目:プリプロセッサはなぜここで定義していますか?これはenumの完璧な仕事のようです。次に、それらを接頭辞(SM_)の必要性を除去するために名前空間/構造体に入れることができます。または、C++ 11の新しいenum classを使用するだけで、javas列挙型とよく似た動作をすることができます。私は可能なところでプリプロセッサを避けるでしょう。単にテキストを置き換えるだけなので、スコープなどを尊重しないので、セミコロンのように問題に陥るのが簡単になります。

2

#include <constants.h>を使用するか、このファイルを含むファイル名を使用してください。また、セミコロンも必要ありません。 #definesは、コンパイラによってコードに対して行われたテキスト置換です。

+1

"constants.h"ではなく、 - コンパイラはインクルードを< >、私はこのエラーを複数回使用しました。 –

+0

@TomTanner合意。 – Sid

+0

@TomTannerそれを回避するために、-I/path/to/includeを使用することはできますが。 – Sid

3

問題は、yuuが#defineの後にセミコロンを持つことです。これは、あなたが "定数"を使用することを妨げる唯一のものです。これは技術的に定数ではありません。それらはプリプロセッサ定義です。

論理的には、C++コンパイラは、プリプロセッサ、つまり#で始まるディレクティブを実行するテキストフィルタを通じて、プログラムのテキストを実行します。 #defineディレクティブは、プリプロセッサに、その左部分のすべての出現箇所を見つけて、それらを正しい部分にそのまま置き換えるように指示します。あなたのケースでは、セミコロンが含まれているため、置換後に無効な式が返されます。例えば、

if (command == SM_DISCARD) ... 

if (command == 1005;) ... 

になるとこれは誤りで、コンパイラが無効な構文としてそれを報告します。

0

cppファイルは必要ありません。ヘッダーを含めるだけで十分です。

プリプロセッサは、後にあるものを含めて定義を拡張します。

int x = SM_START; 

まだ合法である

int x = 1001;; 

に変換されます:

SM_STARTはそうのような表現が1001;

になります。

しかし、そのセミコロンは次のようにトラブルにつながる可能性がある:に展開されます

int x = SM_START * 10; 

int x = 1001; * 10; 

明らかに違法です。

また、プリプロセッサディレクティブをグローバルと混同しないでください。おそらくグローバルを使用すべきではないが、#definesを使用すると、class Globalを定義するか、またはnamespaceでグループ化された変数を使用するよりも悪い可能性があります。

+0

それで私は良い練習をしようとしているのですか?この考え方は、複数のプロセスにアクセスする必要があるため、この「定数」がlibに作られるということです。これを行うより良い方法があれば、私がしていることが正しいかどうか分からないので、私に教えてください。 – PTBG

+0

@PTBGは本当にありません。 1.グローバルは*一般的に*悪いです。 2.グローバルを使用する場合は、それらを静的なconstメンバーとしてクラスに入れるか、名前空間内のextern変数として配置します。 –

関連する問題