好きなおでんの具材ドラフト会議しましょう

C++の超初心者です。コードの書き方の作法について、教えてください。


今、
・main関数のあるmain.cpp
・main内で使う関数Aを宣言した functions.h
・関数Aを定義した functions.cpp
があって、
この関数Aの戻り値が「string型」であったとします。

-----------
このとき、まずfunctions.hの中で
#include <string>
が必要になるわけですが、そうしておけば、

functions.cppでは
#include "functions.h"
をする時に関節的に<string>がincludeされますので、
#include <string> は書かなくても良いことになります。

-----------
しかし、そうすると、このfunctions.cppのソース単体だけを見た時、
#include <string> をしていないのに、中ではstring型をバンバン使用しているという、
ちょっと気持ちが悪い状態になってしまいます。

また、もしmain.cppの中でstring型が使いたくなったときも、
#include "functions.h"をしておりますから、
main.cppに#include <string>は必要ないということになります。
しかし、これもやはりなんだか気持ちが悪い状態です。
また、将来的に関数Aがいらなくなった時、不用意に#include "functions.h"を外すと、
<string>がincludeされていない状態になり、混乱を招くような気がします。

-----------
かといって、二重・三重にincludeを命令することを承知で
(インクルードガードがあるから問題は生じないだろう、という期待をこめて)
functions.cppやmain.cpp内で #include <string> をするのも、よろしくないように思います。
(<string>の中身が何度も展開されてしまい、無駄にコンパイルに時間がかかるので)


この「気持ち悪さ」をうまく払拭する方法、正しく払拭する方法はあるのでしょうか。

質問者からの補足コメント

  • うーん・・・

    stringの場合はfunctions.hに#include <string>は不要なようなのですが、
    たとえば関数Aの戻り値や引数にvectorを使いたい場合は、
    functions.h内に#include <vector>が必要になるようです。

    この場合、functions.cpp(や、あるいはmain.cpp内でvectorを使いたくなった場合)では、
    #include "functions.h"をしておけば#include <vector>は必要ないわけですが、
    ここで「<vector>を(直接)インクルードしていないのにvectorを多用している、ように見える」状況が発生します。

    この「気持ち悪さ」はうまく払拭できるのでしょうか。
    あるいは、そういうものだと思って諦めるものなのでしょうか。

      補足日時:2016/10/31 14:40
  • すみません、いろいろと勘違いがあったようです。
    一旦質問を閉じさせていただきます。お返事いただいた方々、ありがとうございました。

      補足日時:2016/10/31 17:20

A 回答 (2件)

「stringを使うには、ソースファイルに #include <string> を書かなければならない」


「function.cppでstringを使うのなら、 function.h に #include <string> を書かなければならない」
って思い込みを変えることでしょう。

> 将来的に関数Aがいらなくなった時、不用意に#include "functions.h"を外すと、
> <string>がincludeされていない状態になり、混乱を招くような気がします。

これが考えられるなら「 function.h に #include <string> を書かない」ことです。
ライブラリを見ていると、「 XXsub.h を使う場合は先に XXcore.h をincludeしておく」といった使い方をしているものをよく見かけます。
同様に、 「function.hを使うときには、先に#include <string>しておく」と決めてしまいましょう。
includeを忘れたところで、コンパイル時にエラーになるだけです。
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。

> 「stringを使うには、ソースファイルに #include <string> を書かなければならない」
> 「function.cppでstringを使うのなら、 function.h に #include <string> を書かなければならない」
> って思い込みを変えることでしょう。

そうだったのですね。
実験してみたところ、functions.hから#include <string>を取り除いても、コンパイルは通りました。

しかし、さらに実験してみたところ、これが<vector>や<map>の場合ですと、
functions.hに#include <vector>を書いておかないと、コンパイル時にエラーが出てしまうようです。

<string>と<vector>で違いが出る理由はよくわからないのですが、
たとえば<vector>を関数Aで使いたい場合は、どうするのが適切なのでしょうか。

functions.hで#include <vector>をしなければならないのは確定的なようなのですが、
functions.cppやmain.cppにも本当は#include <vector>を書いて、「気持ち悪さ」を拭いたいところです。

お礼日時:2016/10/31 13:15

う~ん, 「思い込みを変える」という点については #1 に同意するけど, 個人的には方向性は真逆で


使うならとにかく #include しろ
って思う. もちろん「無駄にコンパイルに時間がかかる」のはその通りっちゃその通りだけど, 現実的にどのくらい効いてくるのかなぁ.

あと「#1 へのお礼」については実際のコードを見てみないとなんともいえん. <string> のときと <vector> のときとで, それぞれどんなコードを書いてみたんでしょうか?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報