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つで完結するプログラムなんてそうそう書かないと思いますが、
皆さんはどうやって外部関数を参照しているのかわかりません。