C++で外部クラスを使用したプログラムがコンパイルできない
C++初心者です。複数のファイルを取り込んだプログラムがコンパイルできず、その理由もわかりません。
A.cpp
#include "B.h"
int main(int argc, char **argv) {
B test;
test.show(*argv);
return 0;
}
B.h
#pragma once
#ifndef __B_H__
#define __B_H__
#include <string>
class B {
public:
void show(std::string);
};
#endif
B.cpp
#include "B.h"
#include <string>
#include <iostream>
using namespace std;
class B {
public:
void show(const char *var) {
cout << var << endl;
}
};
これでコンパイル
g++ -o a.exe A.cpp
すると
/tmp/ccGn41oP.o:A.cpp:(.text+0x4c): `B::show(std::string)' に対する定義されていない参照です
/tmp/ccGn41oP.o:A.cpp:(.text+0x4c): 再配置がオーバーフローしないように切り詰められました: R_X86_64_PC32 (未定義シンボル `B::show(std::string)' に対して)
collect2: エラー: ld はステータス 1 で終了しました
こうなってしまいます。
これはどういうエラーなんでしょうか。
こんな初歩的な質問で恐縮ですが、教えてください。
ご回答について
ご回答ありがとうございます。
コンパイルの流れを理解していませんでした。
おっしゃる通り、
g++ -c B.cpp
を実行したところ、
$ g++ -c B.cpp
B.cpp:8:7: エラー: ‘class B’ が再定義されています
class B {
^
In file included from B.cpp:1:0:
B.h:8:7: エラー: ‘class B’ の前の定義
class B {
^
となってしまったため、プロトタイプの実装本体はクラス宣言しないのかと思い、
下記に変更して再度実行しました。
B.cpp
#include "B.h"
#include <string>
#include <iostream>
using namespace std;
void show(const char *var) {
cout << var << endl;
}
これで"B.o"というファイルが生成され、改めて
g++ -o A.exe A.cpp
を実行したものの、エラーの内容が変わりませんでした。
sayuri さん
ちなみにですが・・・
引数を
void show(std::string var);
に統一し、
g++ -c B.cpp g++ -o A.exe A.cpp
を行うと
$ g++ -o a.exe A.cpp /tmp/ccSVMoNA.o:A.cpp:(.text+0x4c): `B::show(std::string)' に対する定義されていない参照です /tmp/ccSVMoNA.o:A.cpp:(.text+0x4c): 再配置がオーバーフローしないように切り詰められました: R_X86_64_PC32 (未定義シンボル `B::show(std::string)' に対して) collect2: エラー: ld はステータス 1 で終了しました
というエラーになります。
http://d.hatena.ne.jp/pknight/20090826/1251303641
このブログを見ると、この場合はtemplate関数の場合ですが、
「この関数は使われていないから.objを生成しても実態がないのでA.cppからは実装が見えません」
というようなことが書いてありました。
もしこれと同様の現象が起きているのだとすると、今回show()関数はグローバルメンバ関数ではなくクラスメンバ関数なのでA.cppから見ることはできない
ということになってしまうんでしょうか。
言語仕様をほとんどよくわかっていないので、さすがにそんなことはないんじゃないかと思いますが・・・
C++開発者の方も、実行ファイル1つで完結するプログラムなんてそうそう書かないと思いますが、
皆さんはどうやって外部関数を参照しているのかわかりません。