• 締切済み

「C++ヘッダの肥大化」について

FrazerDebuManの回答

回答No.4

定義と実装をそれぞれのヘッダファイルで書きます。 実装のヘッダが定義のヘッダをインクルードするのです。 あるいはそのクラステンプレートを使用するソースで両方のヘッダをインクルードするのです。 昔使用していたSTLPortはそういう手段を取っていました。

関連するQ&A

  • C++ヘッダの肥大化

    最近、テンプレートクラスとインライン関数を多用しているため、ヘッダファイルの肥大化が気になります。 ヘッダが肥大化するとコンパイル時間も大きくなり、更にヘッダファイルの可読性も落ちてしまうと思います。 また、ライブラリ化するときはコードを隠蔽したいのですが、ほとんどがヘッダファイルに実体があるため隠蔽できません。 インライン関数やテンプレートクラス、テンプレート関数は必ずヘッダファイルに書く必要があるのでしょうか。 標準ヘッダファイルでは「*.cc」という実体コードをインクルードしているので、それに習うべきなのでしょうか。

  • C言語のヘッダファイルの使い方

    ヘッダファイルの使い方について質問です。 ソースファイルA、ソースファイルBで共有して使用したい変数がある場合、 Aでは「int a」と宣言し、Bでは「extern int a」と宣言すれば 同じ変数を共有出来ると認識しています。 それをヘッダファイルへ記述しておきたい場合にはどのように 宣言しておけば良いのでしょうか? ヘッダファイルに「int a」と宣言した場合は両方のソースファイルで includeした時に多重定義でエラーとなります。 では「extern int a」と宣言しておいて、両方のソースファイルで includeするのが正しいのでしょうか? 初歩的な質問で申し訳ないですが、有識者の方、教えてください。

  • ポインタによる包含&ヘッダにincludeしない、 場合でtemplateの定義に…

    class Bの宣言をしているヘッダ中で class A; を、前方宣言し、そのポインタだけを持たせ、ソースファイルのほうにclass Aの中身が分かるように、#includeして、ソースファイルに関数の実装やstatic変数の定義を書いていた、とします。 しかし、templateを使う関数についてはコンパイル時に解決できないといけないので、それだけはヘッダに持ってきました。 その時 includeが一切書かれていない、class Bのヘッダ内において class Aのメンバを参照するようなコードを書いたとき クラス外、クラス内、いずれに書いても 正常にコンパイルできました。 通常の関数では当然無理なので、もともとtemplateがコンパイル時解決を強要するものなのでそういう仕様にしててくれてると考えられますが 1.これは、C++の標準仕様でしょうか?それとも処理系依存でしょうか? あと、templateに関して 2.特殊化ならソースにかけるのは標準仕様でしょうか?それとも処理系依存でしょうか?

  • C++のヘッダーについて

    C++のプログラミングをしています そこで出てきた問題なのですが・・・ class Aのヘッダファイルa.hをほかのcppファイルにインクルードすると、 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません error C2146: 構文エラー : ';' が、識別子 'test' の前に必要です。 とほかのヘッダファイルでコンパイルエラーがでます ヘッダファイルをインクルードしたときのみこのエラーがでて困っています。 解決法や、ヒントになりそうな事例を知りませんでしょうか?

  • ヘッダーファイルでは、他のヘッダーファイルをインクルードできないのか

    Javaを仕事で使っています。 最近趣味でC++を始めました。色々形式の違いに戸惑っています。 C++では関数を宣言しなければならないので、クラス名と同じヘッダーファイルにそのクラスで使う関数を宣言して、それをインクルードしています。 そこで今、壁にぶちあたりました。 あるクラス(仮にFooとします)の関数で、他のクラス型(Hogeとします)を引数に取りたいので、ヘッダーファイルにそれを宣言しようとしているのですが、コンパイルエラーになってしまいます。 Foo.hは以下のような感じ。 #include Hoge.h 中略 GetHoge(Hoge hoge); コンパイルエラーでは error C2011: 'Hoge' : 'class' 型の再定義 などと言われます。 クラスとその同名のヘッダーファイル、という形式を変えずに 他のクラス型を引数にとる関数を作るには、どうしたらよいのでしょうか? C++に関しては全くの素人です。詳しい方、ご教示願います。

  • C言語のヘッダファイル

    前回のC言語のコンパイラの質問で、たくさんのご回答ありがとうございました。 おかげさまでコンパイラはなんとかなりそうですが、ひょっとしたらまた同じ質問を載せるかもしれません(^^; 今回はC言語のヘッダファイルを自分で作ってみたいんですが、よくわかりません。 microsoft visual studioのvisual c++付属のINCLUDEフォルダにある、stdio.hを開いてみたのですが、基本のprintf()やscanf()なども、どう定義されているか わからず終いでした。本などでもいまいち詳しく書いていなく(そう思うのは僕だけ?)、困っています。c言語のヘッダファイルとc++のヘッダファイルは やっぱり別ものなんでしょうか?ご回答おまちしております。

  • ヘッダーの多重定義での疑問です。

     Cで開発をしているのですが、ヘッダーファイルでの定義ではたとえば、int a と か double hoge とか定義して、そのヘッダーファイルを複数の cファイルが読み込むと多重定義になりますよね? hoge.h int a; // 多重定義 このヘッダーを複数の.cファイルに読み込む しかし、自分のプロジェクトだと、ヘッダーファイルにint aとかdouble hogeとか 定義してもエラーにならないんです。 ただし、int b = 10;のように代入すると多重エラー また、試しに新しくプロジェクトを作ってヘッダーで定義すると多重定義でエラーでした。

  • c++におけるtemplateについて

    c++の自作templateを関数宣言部と関数定義部とで、ファイルを分割する事を考えているのですが、エラーが出てtemplateをincludeすることが出来ないでいます。 例えば、 <ファイル:test.H> #ifndef test_H #define test_H #include <iostream> template<class T> class test { private: int row_, col_; public: test( int , int ); }; #endif <ファイル test.C> #include "test.H" template<class T> test<T>::test(int a, int b) :row_(a), col_(b) { std::cout << "コンストラクター" << std::endl; } <ファイル main.C> #include "test.H" #include<iostream> int main() { test a( 3, 3) return 0; } のようにtemplateファイルを分割した場合、 undefined reference to `test<double>::test(int, int)' collect2: ld returned 1 exit status のようなエラーがでます。 書籍:新c++言語入門・シニア編(下)の29章には「export」を関数定義部に付ければ良いような記述がありましたが、エラーを解決することが出来ませんでした。 main.Cにて、test.Cをインクルードするとこの問題を回避することが出来るのですが・・・。 そもそもtemplateは上記のように宣言部と定義部とを別々のファイルにすることはできないのでしょうか?

  • ヘッダファイルにおける文字列リソース定義

    C言語(主にVC++)で開発をしていると、よく、 const char MSG_HELLO[] = "HELLO!"; のように、ヘッダファイル中で、文字列リテラルを定義します。 自分もいつのまにかこのようにリソース定義するようになっていましたが、初期の頃から疑問だったのは、extern宣言せずにchar配列を宣言しているから、コンパイラが最適化しなかったら、上記宣言のあるヘッダファイルを読み込んで、その定義を使った個所のあるソース分文字列リテラルがメモリ上に確保されてしまうのではないか、、?ということです。 つまり、本来なら const char* MSG_HELLO[] = "HELLO!"; とソースファイル中で定義し、ヘッダファイルには extern const char* MSG_HELLO; とすべきではないか、と思うわけです。ただ実際にこれをやっているとヘッダとソースの両方のメンテナンスが必要になるので、冒頭のように記述しているのだと思いますが。 この、本来なら下記のようにすべきだが、コンパイラの最適化(リソースのプール)を期待して最初のように書いている、という解釈は正しいでしょうか?

  • C言語でヘッダファイルにグローバル変数を宣言する

    main.hに static int a; と記述し、main.cで #include "main.h" [省略] a=10; のように使用して、-Wallをつけてコンパイルすると、main.cで使用しているにも関わらず、 'a' defined but not used という警告が表示されます。 同様に、関数においても、ヘッダファイルでstaticをつけると ‘~’ declared ‘static’ but never defined と警告されます。 静的グローバル変数などは、ソースファイル内で宣言しなければいけないのでしょうか?ヘッダファイル内で宣言しても警告が出ないような方法はありますか?