1

私のコードは次のとおりです。

test.cpp

#include<iostream>
#include<boost/bind.hpp>
#include "extern.h"
using namespace std;
using namespace boost;
int fun(int x,int y){return x+y;}
/*
 *void add(int &m,int &n);
 */
int main(){
    int m=1;int n=2;
    cout << m << "  "<< n << endl;
    add(m,n);
    cout << m << "  "<< n << endl;
    return 0;

}

extern.h:

#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;
void add(int &n,int &m);

extern.cpp:

#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;

extern int m;
extern int n;

void add(int &n,int &m) {
    n = n+1;
    m = m+1;
}

でコンパイルすると

g++ -Wall -o test test.cpp

次のようになります。

/tmp/ccMHVRNo.o: In function `main':
test.cpp:(.text+0x7b): undefined reference to `add(int&, int&)'
collect2: ld returned 1 exit status

しかし、私がそれをコンパイルすると:

g++ -Wall -o test test.cpp extern.cpp

それはうまくいきます:

$ ./test
1  2
2  3

その理由は、関数test.cppの実装が見つからないことです。add()

しかし、追加extern.hしましたがtest.cpp、「未定義の参照」とまだ表示されているのはなぜadd(int&, int&)ですか?

4

3 に答える 3

3

関数の実装はvoid add(int&,int&)、ソース ファイル extern.cpp にあります。コンパイラは、ユーザーが通知するまで、このファイルがプログラムに関連していることを認識できません。

コマンド ラインですべてのソース ファイルを指定する必要があります。

g++ -Wall -o test test.cpp extern.cpp

すべてのソース ファイルのコンパイルを避けたい場合は、コンパイル済みのオブジェクト ファイルを指定することもできます。

g++ -Wall -o test test.cpp extern.o

どのコマンドをコンパイルする必要があるかを毎回考えたくない場合は、make を使用しMakefile、ターゲットのビルド方法を定義する with ルールを作成する必要があります。メイクファイルを使用すると、すぐに開始できます

make

そして結果を得る。

于 2013-06-06T14:39:24.307 に答える
3

ヘッダー ファイルは、関数のプロトタイプextern.hがどのように作成されるかをプログラムに伝えるだけです。リンカーは関数の実際の実装を必要とするため、コード参照を探しますが、必要なすべてのファイルをコンパイラーに提供しない限り、それを見つけることができません (この場合は、リンカーが検索時に必要とするファイルです)。関数)。add(int&,int&)extern.cppadd

于 2013-06-06T14:40:07.990 に答える
1

これは通常の式です。

g++ -Wall -c test.cpp
g++ -Wall -c extern.cpp
g++ -o test test.o extern.o

ワンライナーもありますが、それらは大規模なプロジェクトにはあまり適していません。

于 2013-06-06T14:41:22.933 に答える