web-dev-qa-db-ja.com

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

ヘッダーファイルについて常に混乱していました。それらはとても奇妙です:.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
}
...
25
Oleh Prypin

Lzz を使用できます。これは、C++構文で記述された宣言を受け取り、ヘッダーファイルとソースファイルを生成するコマンドラインツールです。

3
Mario Becerra

よりリファクタリングに適した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年以上(私が使用した限り)あります。

16
Berin Loritsch

Java開発者になります。

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

13
Paul Butcher

Hwaci(SQLiteとFossilを行う人)の makeheaders プログラムに興味があるかもしれません。

Fossilの構築方法 も見てください。

8
Benoit

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

クラスの多くは、現在の.cppファイルの先頭から始まります。複数の場所で使用できるように安定したら、ヘッダーにカットアンドペーストします。クラスはしばしばそれが現れたのと同じくらい速く消えますが。

5
Sjoerd

ヘッダー(.h)ファイルはインターフェースをコードに記述します。これはその他コードが参照するのみビットであるためです。

ソース(.cpp)ファイルは、他の誰も知る必要のないコードの実装を提供します。

あなたは.cppを含まない.hファイルを含みます...

正しい。

このコードのコンシューマーとして必要なのはヘッダーファイルだけです。これにより、コンパイラーは、コードで使用できる内容を認識して作業することができます。この時点では、C++ソースコードはどのような形でも使用されていません(または、少なくともすべきではありませんです)。

...しかし、.cppもどういうわけかコンパイルされます。

はい、ですが、完全に個別にです。

使用しているモジュール/ライブラリの.cppファイルは、そのライブラリの開発者によってオブジェクトファイル(.o/.dll)にコンパイルされます。そのオブジェクトファイルには、ヘッダーファイルで説明されているものと同じ「形状」のエントリポイントが含まれます。

link完成した実行可能ファイルにアクセスすると、そのオブジェクトファイルが必要になります。この時点で、リンカーはオブジェクトファイルの内容を取得して実行可能ファイルに埋め込むことができます(静的リンク用です。動的リンクはより複雑)
基本的に、リンカーは、ヘッダーファイルでの表示と実際の内容に基づいて、コードが呼び出すことができるエントリポイント間で「ドットを結合」する必要があります期待ライブラリ自体)。

0
Phill W.