C++ での一般的な方法は、.h
(または.hpp
) 内の宣言と 内の実装を分離すること.cpp
です。
主な理由は 2 つあります (他にもあるかもしれません)。
- コンパイル速度 (1 つのファイルだけを変更する場合、すべてを再コンパイルする必要はありません。
make
事前にコンパイルされた.o
ファイルからリンクすることができます) - 前方宣言が必要になる場合があります (
class A
依存のclass B
実装とclass B
onの実装の場合class A
) ... しかし、私はこの問題を頻繁に抱えているわけではなく、通常は解決できます。
オブジェクト指向プログラミングの場合、次のようになります。
QuadraticFunction.h
:
class QuadraticFunc{
public:
double a,b,c;
double eval ( double x );
double solve( double y, double &x1, double &x2 );
};
QuadraticFunction.cpp
:
#include <math.h>
#include "QuadraticFunc.h"
double QuadraticFunc::eval ( double x ){ return c + x * (b + x * a ); };
double QuadraticFunc::solve( double y, double &x1, double &x2 ){
double c_ = c - y;
double D2 = b * b - 4 * a * c_;
if( D2 > 0 ){
double D = sqrt( D2 );
double frac = 0.5/a;
x1 = (-b-D)*frac;
x2 = (-b+D)*frac;
}else{ x1 = NAN; x2 = NAN; }
};
main.cpp
:
#include <math.h>
#include <stdio.h>
#include "QuadraticFunc.h"
QuadraticFunc * myFunc;
int main( int argc, char* args[] ){
myFunc = new QuadraticFunc();
myFunc->a = 1.0d; myFunc->b = -1.0d; myFunc->c = -1.0d;
double x1,x2;
myFunc->solve( 10.0d, x1, x2 );
printf( "soulution %20.10f %20.10f \n", x1, x2 );
double y1,y2;
y1 = myFunc->eval( x1 );
y2 = myFunc->eval( x2 );
printf( "check %20.10f %20.10f \n", y1, y2 );
delete myFunc;
}
makefile
次に、次のようにコンパイルします。
FLAGS = -std=c++11 -Og -g -w
SRCS = QuadraticFunc.cpp main.cpp
OBJS = $(subst .cpp,.o,$(SRCS))
all: $(OBJS)
g++ $(OBJS) $(LFLAGS) -o program.x
main.o: main.cpp QuadraticFunc.h
g++ $(LFLAGS) -c main.cpp
QuadraticFunc.o: QuadraticFunc.cpp QuadraticFunc.h
g++ $(LFLAGS) -c QuadraticFunc.cpp
clean:
rm -f *.o *.x
しかし、私はしばしば非常に不便だと思います
特に、コードを大幅に変更する場合 (たとえば、開発の初期段階で、プロジェクト全体の全体的な構造についてまだ確信が持てない場合)。
- クラス構造に大幅な変更を加える場合、コードの一部との間
.cpp
を常に行き来する必要があります。.h
- エディターとプロジェクト フォルダーに 2 倍のファイルがあり、混乱しています。
- いくつかの情報 (関数ヘッダーや など
QuadraticFunc::
) を 2 回記述する必要があり、多くのタイプミスや不一致が発生する可能性があるため、コンパイラは常に文句を言います (私はそのような間違いを頻繁に行います)。 - 編集しなければならないクラスを追加/削除/名前変更するたびに
Makefile
、コンパイラ出力から追跡するのが難しい他の多くの間違いを犯します (たとえば、コードがすべての依存関係を再コンパイルするように Makefile を書くのを忘れることがよくあります)。編集 )
この観点から、私は Java の仕組みがより好きです。このため、すべてのコード (実装を含む) を に入れるだけで C++ プログラムを作成していました.h
。このような:
#include <math.h>
class QuadraticFunc{
public:
double a,b,c;
double eval ( double x ){ return c + x * (b + x * a ); }
double solve( double y, double &x1, double &x2 ){
double c_ = c - y;
double D2 = b * b - 4 * a * c_;
if( D2 > 0 ){
double D = sqrt( D2 );
double frac = 0.5/a;
x1 = (-b-D)*frac;
x2 = (-b+D)*frac;
}else{ x1 = NAN; x2 = NAN; }
};
};
次のようなユニバーサルデフォルトメイクファイルを使用します。
FLAGS = -std=c++11 -Og -g -w
all : $(OBJS)
g++ main.cpp $(LFLAGS) -w -o program.x
(main.cpp
同じままです)
しかし、より複雑なプログラムを書き始めると、常にすべてを再コンパイルする必要があるため、コンパイル時間が非常に長くなり始めます。
make
(コンパイル時間の高速化)の利点を利用し、プログラム構造をJavaのような方法で整理.h
する方法はありますか(別のandではなくクラス本体のすべて.cpp
)、はるかに便利ですか?