0

私のコードでは、3 つのクラスを使用しました。すべてのクラスは個別のファイルにあります。そしてMakefile、それらをコンパイルしてリンクするために使用しています。以下の実装を参照してください。

class Medicine 
{ 
   int a;
}

class Pain:public Medicine 
{
   int b;
}

class Comb:public Pain   
{
    string salt,com;
}

すべてのクラスには、3 つのクラスすべてで、パラメータ化されたコンストラクタ、仮想デストラクタ、および同じ名前の関数がありcall()ます。そしてcall()、のようです

call()
{
     cout<<"You are in class the_name_of_the_class"<<endl;
}

のコードは次のmain.cppようになります。

int main()
{       
    Medicine *p[2];
    p[0]= new Comb("Salt","Com",2,110);
    p[1]= new Comb("SALT","COM",1,100);

    p[0]->call();

    delete p[0];
    delete p[1];
    return 0;
}

このプログラムを実行すると、期待どおりの出力が得られました。しかし、Medicine::call() を仮想関数に変更し、再度makeコマンドを使用すると、すべてのファイルが最新であると表示されます。を変更medicine.hしたので、makeの新しいバージョンを作成する必要がありmedicine.oます。medicine.oを変更したのに古いと見なされるのはなぜmedicine.hですか?

Makefile は次のようになります。

using .PHONY:clean
OBJ:=medicine.o pain.o comb.o main.o
SOU:=medicine.cpp pain.cpp comb.cpp main.cpp

main:$(OBJ)
        g++ -o $@ $^

%.o:%.cpp
        g++ -c -o $@ $<

clean:
        rm *.o main

もしあなたがmedicine.hの実装を見たいなら、

class Medicine
{
    int cost;

 public:

    int getCost();
    void setCost(int);

    Medicine();
    Medicine(int);
    Medicine(Medicine &a);
    virtual string getCompany(){};
    virtual string getSalt(){};
    virtual  ~Medicine ();
    virtual void call();
};

これは、これらすべての関数が定義されmedicine.hている に含めました。medicine.cpp

4

4 に答える 4

3

問題は、medicine.oのみに依存しmedicine.cpp、 に依存しないことmedicine.hです。したがって、欠落している依存関係を提供するようにルールを変更する必要があります。「仮想性」とはまったく関係ありません。

Makefile 自体を依存関係として追加することもできます。これを変更して make を実行すると、再構築されます。

明確にするために、この一般的なルールは次のとおりです。

%.o:%.cpp
    g++ -c -o $@ $<

anyは only にsomething.o依存しsomething.cpp、次のコマンドでビルドする必要があることを意味します。

g++ -c -o something.o something.cpp

ie$@はターゲット名で$<、最初の依存関係です。

フォーマットは

target : <dependencies>
    command
于 2013-08-22T11:20:05.483 に答える
1

makeは言語に対応していないため、関数が仮想かどうかは make にはわかりません。実際には、C++ が何であるか、そこに関数があることさえ知りません。

makeターゲットと依存関係の観点から動作し、それらは明示的に指定する必要があります。ここで、オブジェクトを作成するルールには依存関係にファイルが含まれていないため、ファイルはターゲットに使用されていない.hと推測されます。.8

1 つのファイルを作成するために必要な推移的なインクルードの適切なセットを取得することは、実際には非常に困難です。.cppなどの支援するスクリプトがありますmake_depend.pl

于 2013-08-22T11:24:55.503 に答える
1

問題は、makefile にヘッダー ファイルのソース ファイルへの依存関係がないため、"yh" が変更されたときに "x.cpp" を再コンパイルする必要があることを認識していないことです ("yh" が含まれているため)。 「x.cpp」による)。

次のようなルールを設定することで、これを修正できます。

medicine.o : medicine.cpp medicine.h 

ただし、ソース ファイルの数が多くなり、ヘッダーとソースの関係がより複雑になると、実際に必要なヘッダー ファイルを忘れたり除外したりすることになります。これは常に発生します。

私が通常行うことは、次のようなものです。

SOU = medicine.cpp pain.cpp comb.cpp main.cpp
... 

main:$(OBJ) .depends

...

.depends: $(SOU)
     g++ -MM $(SOU) > $@

include .depends

これが行うことは、コンパイラがルールをファイルに生成できる.dependsようにすることです。そうすれば、どこかでファイルを更新するときに修正を「忘れる」ことはありません。

編集: 大規模なプロジェクトの場合、.cpp ファイルが変更されるたびに、コンパイラはプロジェクト内のすべてのファイルのすべての依存関係を整理する必要があるため、単一の依存関係ファイルを使用することはお勧めできません。しかし、小さな趣味のプロジェクトでは問題ありません。.depends大規模なプロジェクトの場合、多くのファイル (ソース ファイルごとに 1 つ、おそらくディレクトリ内)を持つという余分なペナルティが発生しますdepends

于 2013-08-22T11:27:00.873 に答える
0

の作業makeは次のようなものです: 依存関係の最新の変更時刻 (medicine.cppたとえば) をチェックし、作成されたmedicine.cppときの最新の変更時刻をチェックしmedicine.oます。両方が同じ場合は再コンパイルされず、そうでない場合は再コンパイルされます。私の場合、medicine.hは変更されましたが、 の最終変更時刻は変更されmedicine.cppません。makeこれが、これを検出できず、再コンパイルされなかった理由medicine.cppです。

于 2013-08-22T11:56:09.680 に答える