C ++ヘッダーファイルが嫌いな場合はどうすればよいですか?


25

私はいつもヘッダーファイルについて混乱していた。それらはとても奇妙です。.cppを含まない.hファイルをインクルードしますが、.cppも何らかの方法でコンパイルされます。

最近、私はチームプロジェクトに参加しました。もちろん、.hと.cppの両方が使用されます。
これが非常に重要であることは理解していますが、複数のクラスのそれぞれにあるすべての関数宣言をコピーアンドペーストすることはできません。

2ファイルの規則を効率的に処理するにはどうすればよいですか?
それを支援するツールはありますか、または以下の例のような1つのファイルを.hと.cppに自動的に変更しますか?(特にMS VC ++ 2010の場合)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...

8
この質問にはいくつかの方法があります。「c ++を使用するときにヘッダーが必要な理由」または「コンパイルすることを意図した現代言語はヘッダーを使用する必要があると思いますか?」それがあるとして、それは持っている私は、フラグの過多オフセットタイトルに」と『憎しみ』を何をしますか。
ティム・ポスト

4
あなたの質問は、あなたがC ++を理解していないように思われます。適切に使用することを学び、より主観的な質問をしてください。
デヴィッドソーンリー

31
最初の文は、「ヘッダーに関するすべてを理解していない」ことを示しています。.hファイルを含めても、対応する.cppファイルは「何らかの方法でコンパイルされません」。.cppファイルを独自にコンパイルします。対応する.cppをコンパイルしていない場合、対応するオブジェクトファイルなしでヘッダーを含めると、リンカが失敗します。
ポール・ブッチャー

5
何をすべきか?バグが多い場合は別の言語を探してください。
ポールネイサン

5
「コピーと貼り付けでは対応できません」について:関数を更新するたびに、関数が呼び出されるすべての場所を更新する必要があります。呼び出し元はヘッダーファイル内の宣言よりも見つけるのがはるかに難しいため、ヘッダーの更新はほんのわずかな詳細です。
シェード

回答:


15

よりリファクタリングしやすいC ++の記述

C ++では、ヘッダーを使用する必要はまったくありません。C#またはJavaの場合と同じように、1つのファイルでオブジェクト全体を定義できます。C開発者は通常、外部呼び出しのみをヘッダーファイルに保持します。すべての内部呼び出しは、.cファイルで定義されます。同様に、C ++ .hファイルをクラス/インターフェース(純粋な仮想抽象クラス)/などのために予約できます。DLLの外部で共有することを目的としています。内部クラス/構造体/インターフェイスなどの場合、必要な.cppファイルを含めるだけです。

#include<myclass.cpp>

これは最も一般的なアプローチではないようですが、合法的なC ++です。それは間違いなくすべての内部コードの可能性です。これにより、内部コードとクラスのセットが大幅に変更され、ライブラリ/実行可能ファイルの外部のコードとやり取りするためのより安定したインターフェイスが提供されます。

1つのファイル内にクラス全体を含めると、必要な処理が簡単になります。メソッドの名前を変更し、そのメソッドが呼び出されるすべての場所を検索しなければならないという問題は解決しませんが、よりわかりやすいエラーメッセージがあることを確認します。ヘッダーでメソッドを一方向に宣言することほど悪いことはありませんが、実装方法は異なります。ヘッダーファイルを呼び出す他のコードは適切にコンパイルされ、リンク例外が発生しますが、実装ファイルはメソッドが定義されていないと文句を言うものになります。(実際のクラス宣言で)所定の場所にすべてのメソッドを定義すると、どのファイルが含まれていても同じエラーメッセージが表示されます。

この質問もご覧ください。C++用の優れたリファクタリングツール

C / C ++がヘッダー/実装ファイルを解決する方法

ベースCレベル(およびC ++はその基盤上に構築されます)では、ヘッダーファイルは、コンパイラーがオブジェクトファイルを作成するのに十分な関数/構造体/変数の約束を宣言します。同様に、C ++ヘッダーファイルは、関数、構造体、クラスなどの約束を宣言します。コンパイラは、スタックなどにスペースを確保するためにこの定義を使用します。

.cまたは.cppファイルには実装があります。コンパイラーは各実装ファイルをオブジェクトファイルに変換するため、未実装の概念(ヘッダーで宣言されたもの)へのフックがあります。リンカは、フックを他のオブジェクトファイルの実装に結び付け、すべてのコード(共有ライブラリまたは実行可能ファイル)を含むより大きなバイナリを作成します。

VS特定

Visual Studioでの作業については、少し簡単にするためのウィザードがいくつかあります。新しいクラスウィザードは、ヘッダーと実装ファイルの一致するペアを作成します。新しいメソッドを宣言できるクラスブラウザ機能もあります。ヘッダーに定義を挿入し、.cppファイルに実装スタブを挿入します。Visual Studioには、これらの機能が10年以上使用されています(使用している限り)。


問題は、私は頻繁にちょうどなど、新たな機能を追加していない、クラスのすべての時間を変更しています、です
オレグPrypin

5
@BlaXpirit:それでは、なぜクラスを常に大幅に変更しているのですか?OOデザインの背後にあるアイデアの1つは、かなり安定したビルディングブロックを多数持つことです。クラスを大幅に変更する場合は、Common LispやPythonなど、より動的な言語が必要です。
デヴィッド

2
それは私がやっていることです。私は「ビルディングブロック」を変更し、新しいものを追加/改善しています
オレグPrypin

C ++はこれまでにないリファクタリングに対応しました。リファクタリングの概念は、Java IDEで簡単に実行できるツールが登場するまで勢いを増しませんでした。注:これらの機能はSmalltalk開発者や他の言語向けにありましたが、多くの人々が利用できるようになるまで主流にはなりませんでした。これまでのところ、C ++でそれをインテリジェントに実装している人はいません。おそらくJetBrainsのResharperでしょうか?私はそれがC#とVBコードを行うことを知っていますが、それがC ++リファクタリングを提供するかどうかはわかりません。
ベリンロリチュ

@Berin:1年か2年前にC ++リファクタリングツールを探して、2つのことを見つけました。当時はかなり高価だったので、試用版は見なかったので、何をしたのかわかりません。さらに、1つはemacsのみを使用していたため、Visual Studioショップでの有効性が制限されます。
デビッドソーンリー

13

Java開発者になる。

C ++での開発を続ける必要がある場合は、IDEを使用してみてください。多くの場合、クラスにメソッドを追加できるメカニズムが提供され、自動的に宣言が.hファイルに、定義が.cppファイルに配置されます。


2
kthx、私は多少Javaを知っていますが、低レベルのWin32 DLLを作成することはできませんか?
オレPrypin

41
理由はわかりませんが、「Java開発者になる」というのはhow辱のように聞こえます:D。
オリバーワイラー

2
低レベルを行いたい場合は、「簡単な言語」に関するすべてを忘れてください。低レベルでは汗と涙がかかります。
バティビックス

5
特に役立つ答えではありません。
ChrisF

1
@OliverWeiler「Java開発者になる」ことをin辱だとは思いません。私はC ++とJavaの両方でプログラミングしますが、動作する(そしてより移植性の高い)コードをじっと見るのがずっと簡単だから、私の好みはJavaです。何らかの理由でヘッダーファイルの存在を嫌う場合、Javaを試すのが正しい選択かもしれません(ヘッダーファイルを嫌うのは奇妙ですが、IDEの変更を検討します)。
トリクシーウルフ14


4

新しいクラスの最初の行を書くとき、それは通常、そのときだけ1つの場所でそれを必要とするためです。後で、より多くの場所で使用される可能性がありますが、最初は通常は使用されていません。

私のクラスの多くは、現在の.cppファイルの先頭から始まります。複数の場所で使用するのに十分な安定性が得られたら、ヘッダーに切り貼りします。多くの場合、クラスは表示された速度で消えます。


-1

C ++ヘッダーファイルの処理に役立つ提案として、「GCC」ライブラリのように、ファイル拡張子やファイルサフィックスなしで使用するのが一般的です。

この場合、「. hpp」(または「 .hxx」)のファイル拡張子またはファイルサフィックスを使用することをお勧めします。

コンパイラ、開発者環境、または構築プログラムを構成する必要がある場合があります。


3
次のようなファイルをインクルードする方法について話しているの#include <iostream>ですか?これらはGCCライブラリだけのものではありません。実際、1997 C ++標準のセクション17.3.1.2で定義されています。そのようなファイルには名前を付けません。可能ですが、C ++標準ライブラリが行った理由は、おそらく名前の競合を避けるためです。コンパイラがヘッダーをインクルードするときに '.h'を自動的に追加すると、実際には奇妙に感じます。そして、c ++標準ライブラリを除いて、接尾辞のない名前のヘッダを見る人はいません。
ヴェドシティ

1
また、私が使用したすべてのコンパイラは、ボーランド(私は非常に嫌いです)を除いて、試すときに '.h'または '.hpp'または '.hxx'を自動的に追加しないことに注意してください接尾辞のないファイルを含めるため。すべてのコンパイラの#include <someclass>ように読まれることを期待しないでください#include <someclass.hpp>。コードが壊れます。
ヴェドシティ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.