2012-03-06 6 views
90

単純なクラスの実装コードと宣言コードを新しいヘッダーとcppファイルに分ける方法が混乱しています。たとえば、次のクラスのコードをどのように分離するのですか?基本的クラスコードをヘッダーとcppファイルに分割する

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y) 
    { 
    gx = x; 
    gy = y; 
    } 

    int getSum() 
    { 
    return gx + gy; 
    } 
}; 
+6

ただ、コメントのカップル:コンストラクタは、常に設定の初期化リストを代わりに使用する必要があります体の中のメンバー。良い説明と簡単な説明については、http://www.codeguru.com/forum/showthread.php?t=464084を参照してください。少なくとも公共の場を上に置くのが通例です。それは何にも影響しませんが、パブリックフィールドはクラスのドキュメントなので、それを一番上に置くのは理にかなっています。 – martiert

+1

@martiertメンバがこのアドバイスに従ってそれらを移動したが、メンバ間の依存関係があり、メンバが宣言の順番で初期化されていることをまだ認識していなかった場合、先頭に 'public:'メンバを持つことは_lot_に影響します。 - ) –

+1

@underscore_dこれは本当です。しかし、やはり、私たちはすべて警告としてエラーとしてコンパイルしており、私たちが考えることができるすべての警告ですよね?それは少なくとも、あなたがこれをねじっていると言うでしょうが、人々は少しの警告に方法を使用し、それらを無視します:( – martiert

答えて

138

クラス宣言はヘッダーファイルに入ります。 #ifndefのガードを追加することは重要です.MSプラットフォームの場合は、#pragma onceも使用できます。また、私はプライベートを省略しています。デフォルトでは、C++クラスのメンバーはプライベートです。

// A2DD.h 
#ifndef A2DD_H 
#define A2DD_H 

class A2DD 
{ 
    int gx; 
    int gy; 

public: 
    A2DD(int x,int y); 
    int getSum(); 

}; 

#endif 

と実装がCPPファイルに行く:

// A2DD.cpp 
#include "A2DD.h" 

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
+27

テンプレートのプログラミングを行っている場合、コンパイル時に正しいコードをインスタンス化するように、すべてを.hファイルに保存する必要があります。それをsloveする方法がわからない、重複シンボルイムとエラーになって – linello

+0

イムは.ld:アーキテクチャx86_64で – drdrdr

+1

のシンボルA2DD :: ./src/rstring.oでA2DD(int型、int型)と./src/A2DD.oを複製しますヘッダーに '#ifndef'というものがありますか? – fritzone

5

関数宣言/定義の修飾構文:

a2dd.cpp

class A2DD 
{ 
private: 
    int gx; 
    int gy; 

public: 
    A2DD(int x,int y); 

    int getSum(); 
}; 

a2dd.h

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
2

あなたはヘッダーファイルで宣言を残します。

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y); // leave the declarations here 
    int getSum(); 
}; 

そして、定義を実装ファイルに入れます。

A2DD::A2DD(int x,int y) // prefix the definitions with the class name 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 

あなたは(例えばヘッダーにgetSum()定義を残す)2を混ぜることができます。これは、コンパイラにインライン展開の可能性を高めるために便利です。しかし、実装を変更すると(ヘッダーに残っている場合)、ヘッダーを含む他のすべてのファイルが再構築される可能性があります。

テンプレートの場合、すべてをヘッダーに保存する必要があります。

+1

ヘッダーファイルにプライベートメンバーと関数を置くことは、実装の詳細が漏れているとは考えられません。 – Jason

+0

@Jason、一種。それらは必要*実装の詳細です。たとえば、クラスがスタック上でどれくらいのスペースを消費するかを知る必要があります。関数の実装は、他のコンパイル単位では必要ありません。 –

3

A2DD.h

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y); 

    int getSum(); 
}; 

A2DD.cpp

A2DD::A2DD(int x,int y) 
    { 
    gx = x; 
    gy = y; 
    } 

    int A2DD::getSum() 
    { 
    return gx + gy; 
    } 

アイデアは、ヘッダーファイル内のすべての機能シグネチャとメンバーを維持することです。
これにより、他のプロジェクトファイルは、実装を知らなくてもクラスの外観を見ることができます。

さらに、ヘッダの代わりに他のヘッダファイルを実装に含めることができます。ヘッダーファイルに含まれているヘッダーは、ヘッダーファイルを含む他のファイルにインクルード(継承)されるため、これは重要です。

1

通常あなたがヘッダファイルで宣言のみと本当に短いインライン関数を置く:たとえば

class A { 
public: 
    A(); // only declaration in the .h unless only a short initialization list is used. 

    inline int GetA() const { 
    return a_; 
    } 

    void DoSomethingCoplex(); // only declaration 
    private: 
    int a_; 
}; 
9

一般に、.hにはクラス定義が含まれています。これはすべてのデータであり、すべてあなたのメソッド宣言。あなたのケースでは、次のように:

A2DD.h: 

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y);  
    int getSum(); 
}; 

そしてあなたの.cppファイルは、このようなメソッドの実装が含まれています

A2DD.cpp: 

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
関連する問題