質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

6965閲覧

ヘッダーの正しい記述方法

Unity-chan

総合スコア20

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2017/01/12 02:19

ヘッダーファイルを使用していていくつか疑問に思った点があるので質問させて頂きました.例として以下ようなプログラムを記述しました.
作業環境はVS Express 2013 for windows desktopです.

C++

1// Header1 2#ifndef __Header1_h__ 3#define __Header1_h__ 4 5#define ARRAY_SIZE 5 6#include <string> 7using std::string; 8 9 10extern void STRFunc1(string filename); 11 12#endif

C++

1// Header2 2#ifndef __Header2_h__ 3#define __Header2_h__ 4 5#include <string> 6using std::string; 7 8 9extern void STRFunc2(string username); 10extern void ARRAYFunc3(int point[ARRAY_SIZE]) 11 12#endif

C++

1// Main関数 2#include "Header1.h" 3#include "Header2.h" 4 5int main (void){ 6 7 ------ 8 9}

①二つのヘッダファイルをインクルードするので
「#include <string>」「using std::string」
がそれぞれ二回実行されることになるのですが問題はないのでしょうか.

②"Header1.h"で定義した
「ARRAY_SIZE 5」
を"Header2.h"で使用できるのはなぜでしょうか.
メイン関数では先に"Header1.h"を展開するので"Header2.h"で記述した「ARRAY_SIZE」が問題なく動作することは理解できます.しかし"Header2.h"単体で見た場合,「ARRAY_SIZE」の定義がないのでエラーが出るのではないのかと考えました.

初歩的な内容ですが,回答よろしくお願いします.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

「#include <string>」「using std::string」
がそれぞれ二回実行されることになるのですが問題はないのでしょうか.

#include <string> : #ifndef XXX / #define XXX / #endif で多重includeを回避してあります。
using std::string : 文法的に、何度現れても問題なし。だけどヘッダ内に書くのは望ましくない。

しかし"Header2.h"単体で見た場合,「ARRAY_SIZE」の定義がないのでエラーが出るのではないのかと考えました.

そのとおり。

投稿2017/01/12 02:42

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Unity-chan

2017/01/12 03:13

回答ありがとうございます. string等の標準ライブラリにはインクルードガードが付いているんですね.きちんと定義を確認しておらず恥ずかしい限りです.
guest

0

ベストアンサー

C++はcppファイルごとにオブジェクトファイルを作成していきます。
その時、ヘッダファイルはcppファイルに継ぎ足されて1枚の大きなテキストファイルになるんだと考えてください。
上の例では全部展開するとこんな感じになります。

#define ARRAY_SIZE 5 /* * ここにずらーっと<string>の中身… */ using std::string; extern void STRFunc1(string filename); // 2回目の<string>は中身展開されずスキップ using std::string; extern void STRFunc2(string username); extern void ARRAYFunc3(int point[ARRAY_SIZE]) int main (void){ ------ }

だからARRAY_SIZEのことも分かるんですね。
でもちょっと危ない書き方なので、極力こういうのは控えましょう。

こういうのの解決策としては

  • ARRAY_SIZEを別のヘッダファイルにして、ヘッダファイル内で読み込む
  • 共通設定がアプリケーション全体で欲しい時は全部のcppファイルで共有するヘッダファイルを作る

なんかがあります。

投稿2017/01/12 03:02

haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

①二つのヘッダファイルをインクルードするので

「#include <string>」「using std::string」
がそれぞれ二回実行されることになるのですが問題はないのでしょうか.

よく発生する問題ですので、ヘッダ・ファイルにはインクルード・ガードをかけることが一般的です。(というか、特殊な事情がないかぎりインクルード・ガードします。)
ですので、stringヘッダもインクルード・ガードされていますので、問題ないです。

②"Header1.h"で定義した

基本的に#includeは#include分の位置に、指定したファイルの内容をそのまま展開します。
現在、コンパイルしているメイン関数のあるソース・ファイルでは、#include "Header1.h"の後で#include "Header2.h"していますから、この場合に限りARRAY_SIZEが既に定義されています。

例えば、#include "Header1.h"#include "Header2.h"を逆順に並べたらエラーがでますし、他のcppファイルで#include "Header2.h"だけを行って、そのcppファイルをコンパイルするとエラーになります。

投稿2017/01/12 02:48

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問