[解決済み】C++の定義をヘッダーファイルに配置するのは良い習慣ですか?
質問
私のC++の個人的なスタイルは、常にクラス宣言をインクルードファイルに、そして定義を
.cpp
ファイルで規定されているのと同じように
に対するロキさんの回答
C++のヘッダーファイル、コードの分離
. 確かに、私がこのスタイルを好む理由のひとつは、Modula-2やAdaのコーディングに費やした年月に関係しているのかもしれません。
私よりずっとC++に詳しい同僚がいるのですが、彼はすべてのC++の宣言は、可能な限り、ヘッダーファイルの中にその定義を含めるべきだと主張しています。彼は、これが有効な代替スタイルであるとか、少しはましなスタイルであるとか言っているのではなく、これが現在誰もがC++で使っている新しい普遍的に認められたスタイルである、と言っているのです。
私は以前ほど体が丈夫ではないので、彼のバンドワゴンにもう少し多くの人が乗るのを見るまでは、このバンドワゴンに乗っていくことにあまり不安を感じないのです。では、このイディオムは実際どのくらい一般的なのでしょうか?
答えの構成を考えるために。それは今 ザ・ウェイ 非常に一般的か、ある程度一般的か、一般的でないか、バグアウトクレイジーか?
解決方法は?
あなたの同僚は間違っています。一般的な方法は、コードを.cppファイル(または好きな拡張子)に置き、宣言をヘッダーに置くことです。
ヘッダーにコードを入れることには、コンパイラがより巧妙にインライン化できるようになるというメリットがあります。しかし、同時に、すべてのコードがコンパイラによってインクルードされるたびに処理されなければならないので、コンパイル時間を破壊する可能性があります。
最後に、すべてのコードがヘッダーである場合、循環するオブジェクトの関係(時には望ましい)を持つことは、しばしば迷惑です。
結論から言うと、あなたは正しく、彼は間違っています。
EDITです。 ご質問の件、考えてみました。そこには 一 テンプレートです。boostなどの新しい"modern"ライブラリの多くはテンプレートを多用し、しばしば"header only."となっています。しかし、これはテンプレートを扱うときにのみ行うべきことです。
EDITです。 ヘッダのみのコードを書くことのデメリットについて、もう少し明確にしておきたいと思う人もいるでしょう。
検索してみると、boostを扱う際にコンパイル時間を短縮する方法を探している人が結構いるようです。例えば Boost Asioでコンパイル時間を短縮する方法 1Kのファイルをboost込みでコンパイルすると、14秒かかることがわかりました。14秒は爆発的な時間ではないかもしれませんが、一般的な時間よりはるかに長く、大規模なプロジェクトを扱う場合はすぐに累積してしまいます。ヘッダのみのライブラリはコンパイル時間にかなり大きな影響を与えます。ブーストはとても便利なので、私たちはそれを許容しているだけです。
また、ヘッダだけではできないこともたくさんあります(boostでもスレッドやファイルシステムなど、部分的にリンクする必要があるライブラリがあります)。例えば、ヘッダのみのライブラリでは、単純なグローバルオブジェクトを持つことができません(シングルトンという忌まわしい方法を取らない限り)。 注意 C++17のインライン変数によって、将来的にはこの特殊な例も可能になるでしょう。
最後のポイントとして、boostをヘッダのみのコードの例として使用する場合、しばしば大きなディテールが見落とされることがあります。
Boostはライブラリであり、ユーザーレベルのコードではないので、そう頻繁に変更されることはありません。ユーザーコードの場合、すべてをヘッダーに記述してしまうと、ちょっとした変更のたびにプロジェクト全体を再コンパイルしなければならなくなります。これはとんでもない時間の無駄です(コンパイルごとに変更しないライブラリの場合はその限りではありません)。ヘッダーとソースの間で物事を分割し、さらに前方宣言を使用してインクルードを減らすと、1日に渡って合計すると、再コンパイルにかかる時間を節約できます。
関連
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] *.h または *.hpp をクラス定義に使用します。
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] C++テンプレート関数定義の.CPPファイルへの格納
-
[解決済み] C++のヘッダーファイルで#ifndefと#defineが使われているのはなぜですか?
-
[解決済み] Javascriptのファイル全体を「(function(){ ... })()」のような無名関数で囲むのは何のためでしょうか?
-
[解決済み] ループ内での変数宣言、グッドプラクティスかバッドプラクティスか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。