🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

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

Q&A

解決済

3回答

7478閲覧

cppファイルとヘッダファイルのどちらでincludeするか

torimingo

総合スコア122

C++

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

0グッド

0クリップ

投稿2021/03/17 08:54

includeの書き方について悩んでいます。
以下に例を示します。
悩んでいるのは、"cat.h"と<iostream>のinclude文をdog.cppに書くか、dog.hに書くかです。
以下の例では、dog.cppに書いています。
どちらに書くのが良いのでしょうか?
理由なども教えて頂けると幸いです。

dog.h

1 #ifndef DOG_H 2 #define DOG_H 3 4 //#include <iostream> 5 //#include "cat.h" 6 7 class Cat; 8 9 class Dog 10 { 11 public: 12 Dog(); 13 ~Dog(); 14 Cat *cat; 15 }; 16 17 #endif

dog.cpp

1 #include "dog.h" 2 #include "cat.h" // dog.hに書くべき? 3 #include <iostream> // dog.hに書くべき? 4 5 Dog::Dog() : 6 cat(new Cat) 7 { 8 std::cout << "wan" << std::endl; 9 } 10 11 Dog::~Dog() 12 { 13 delete cat; 14 }

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

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

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

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

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

guest

回答3

0

ベストアンサー

<iostream>

これはdog.cppにてinclude.
dog.hをincludeする側に<iostream>を強制的にincludeさせる理由が全く無いので.

Cat.h

これは状況次第.

仮に,dogクラスのメンバであるCat *cat;がprivateだったならば,dog.cppにてinclude.
その理由は<iostream>と同じ.

しかし,現状はpublicなので,dogクラスを利用する側がCatクラスの定義を必要とする場合にはCat.hをincludeする必要が生じる.
これを,
dog.hに #include "Cat.h" とか書いておくことで面倒が無いようにしておくか,
それとも,dog.h の利用側が必要に応じて Cat.h をincludeするという話にするのかは,方針に依る.



[補足追記]

※何やら他者の回答のコメント欄にて「privateがどうの」という騒ぎが起きているのは
この私の回答のせいなのかもしれない(?)ので,念のため補足しておく.

もしも,Dogクラスがこのような形だったとしたら…

C++

1//dog.h 2class Cat; 3 4class Dog 5{ 6//publicかprivateかはともかくとして 7 Cat cat; //Cat型のメンバ変数 8};

メンバ変数cat が publicだろうがprivateだろうが,Cat型の定義を与えないとコンパイルエラーになる.
「Cat型ってのは何なんだよ?」というわけだ.
このdog.hをincludeする場所ではCat型の定義が必ず必要(≒Cat.hのincludeが必要).
(この場合,include順とかも面倒だし,dog.hに#include "Cat.h"とか書いておくのがまぁ無難であろう.)

しかし本件の例では,メンバはCat型ではなくて Cat *cat; である.

C++

1//dog.h 2class Cat; 3 4class Dog 5{ 6//publicかprivateかはともかくとして 7 Cat *cat; //Cat型ではなく Cat* 8};

「"Cat"っていうのは,何らかのclassの型名なんだけどさー」(←前方宣言による)
「で,Cat*型のポインタ変数catがあってさー」
というだけの話をしている限りは,Cat型の具体的な定義が無くても良いから,とりあえずはコンパイルエラーにはならない.(つまり,Cat.hのincludeはとりあえず必要ではない)

で,この回答で「privateが云々」と言っているのは,
【もしも cat がprivateであれば,dog.hをincludeしてDogクラスを使う側では cat に触れることは無いハズなのだから,Cat型の定義が追加で必要になることも無い(Cat.hのincludeが必要になることは無い)ハズ】
という話.
Dogクラスを使う側では Cat.hのinclude が必要になることは無いハズなのだから,dog.hに#include "Cat.h"とか書いても何の利便性ももたらさないし,
それどころかこれを書いてしまうと,余計な依存関係を作り出してしまうから,書くべきではない.

投稿2021/03/17 09:48

編集2021/03/18 02:24
fana

総合スコア11985

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

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

torimingo

2021/03/17 12:25

ご回答をありがとうございました。 privateとpublicに分けて考えるという発想はありませんでした。
fana

2021/03/18 01:25

dog.h内に他のヘッダのincludeを書くか否かは dogクラスを使う側,すなわち dog.h をincludeする側の観点で考えると良いかと. 「コンパイルエラー? …なんだよDog.hの他にCat.hのincludeも必要なのかよ…だったらあらかじめ dog.h にinclude を書いておいてくれよ」と思うようなものであれば,書いておけば良い(使うのが面倒でないという意味で)と思いますし, 「俺はDogクラスを使いたいだけなのに,何故そのことに不要な(無関係な)ものまでincludeされなきゃならんのか?」というようなものは書かないでおくと良いかと.
yohhoy

2021/03/18 07:16

回答後半で言及されているとおり、Catクラスの定義(実体)を必要とするか、Catクラスの存在が宣言されているだけで十分かが本質ですね。 C++言語の場合、private/publicの別でinclude判断基準が変わるケースはまずないと思います。
fana

2021/03/18 07:21

ちょっと最初の回答時点での書き方が雑というか,うまくなかったですね.
guest

0

どちらに書くのが良いのでしょうか?

基本的には、「そのファイルで使うもの」を書くようにしたほうがいいでしょう。

dog.h内ではCatを使っているのでcat.hは呼ぶ、iostreamに依存するものはなにもないのでiostreamは不要、となります。

投稿2021/03/17 08:58

maisumakun

総合スコア145963

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

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

maisumakun

2021/03/17 09:00

循環参照などでヘッダを呼べない、あるいはpimplと呼ばれるように実体を隠蔽したい、というような動機があるのでなければ、クラスは前方宣言ではなくincludeしたほうがいいです。
torimingo

2021/03/17 12:28

ご回答をありがとうございました。 クラスは前方宣言ではなくincludeしたほうが良いのですね。
txty

2021/03/17 12:39

すいません上のメンバ変数がprivateの場合,どうなるんでしょうか
txty

2021/03/17 14:55 編集

いや、maisumakunさんの発言でわからなくなったように感じたんですが。コメントはすいませんでした。あと、他人の迷惑を考えない人間ではないです。
fana

2021/03/18 02:31

(privateがどうのという話が湧いたのは私のせいなのかも? と思ったので,私の回答側に補足を書いてみました)
guest

0

そんなもんコンパイルエラーにならなきゃどーでもいい

投稿2021/03/17 10:49

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問