グローバルに表示されるエンティティは、定義を 1 つだけ持つことができます。hello()
したがって、複数の翻訳単位で同じ関数を定義することはできません。同じ名前の関数を複数回定義する方法はいくつかあります。
オーバーロードされた関数は、引数が何らかの方法で異なる限り、同じ名前を持つことができます。たとえば、各hello()
関数が異なるバージョン間で異なる引数を取るようにすることができます (注: このアプローチはお勧めしません)。例えば:
void hello(bool) { std::cout << "hello(bool)\n"; }
void hello(int) { std::cout << "hello(int)\n"; }
異なる名前空間で名前を定義できます。これにより、完全修飾名が実際には異なります。つまり、異なるスコープを使用するだけで競合が防止されます。たとえば、次のようになります。
namespace a { void hello() { std::cout << "a::hello()\n"; }
namespace b { void hello() { std::cout << "b::hello()\n"; }
static
ローカル ファイル内の関数から関数を呼び出すと仮定すると、キーワードを使用して関数をグローバルに表示される状態からローカルにのみ表示される状態に移動できます。ローカル可視性を持つ関数は、異なる翻訳単位間で競合しません。例えば:
// file a.cpp
static void hello() { std::cout << "a.cpp:hello()\n"; }
void a() { hello(); }
// file b.cpp
static void hello() { std::cout << "b.cpp:hello()\n"; }
void b() { hello(); }
あなたの教えが実際にこれらのバージョンのどれを求めているかはわかりません。ただし、それぞれに用途があり、さまざまなバリエーションを知っておくと便利です。
完全を期すために関数を含める必要があると誰かが主張する場合virtual
: 関数をオーバーライドすると、実際にはオーバーロードも作成されることに注意してください (virtual
ベースの関数とオーバーライドする関数は暗黙的に渡されたオブジェクトが異なります)。つまり、virtual
関数の使用は既に行われています。覆われています。