5

私の宿題は、これが私の宿題です。

5 つのファイルを作成します。Driver.cpp、fh、f.cpp、gh、g.cpp。f と g は、hello という関数を実装する必要があります。ドライバーは f と g から hello を呼び出す必要があります。

出力例:

fからこんにちは

gからこんにちは

何かキーを押すと続行します 。. .

これらすべてのファイルを作成しましたが、理解できないのは、同じ関数 hello() が 2 つのファイルに存在し、driver.cpp ファイルから呼び出される方法です。どんな助けでも大歓迎です!

編集:私が得るエラーは「致命的なエラーLNK1169:1つ以上の複数定義されたシンボルが見つかりました」です。これは、2 つの hello() 関数を参照しています。これを修正するにはどうすればよいですか?

4

2 に答える 2

17

グローバルに表示されるエンティティは、定義を 1 つだけ持つことができます。hello()したがって、複数の翻訳単位で同じ関数を定義することはできません。同じ名前の関数を複数回定義する方法はいくつかあります。

  1. オーバーロードされた関数は、引数が何らかの方法で異なる限り、同じ名前を持つことができます。たとえば、各hello()関数が異なるバージョン間で異なる引数を取るようにすることができます (注: このアプローチはお勧めしません)。例えば:

    void hello(bool) { std::cout << "hello(bool)\n"; }
    void hello(int)  { std::cout << "hello(int)\n"; }
    
  2. 異なる名前空間で名前を定義できます。これにより、完全修飾名が実際には異なります。つまり、異なるスコープを使用するだけで競合が防止されます。たとえば、次のようになります。

    namespace a { void hello() { std::cout << "a::hello()\n"; }
    namespace b { void hello() { std::cout << "b::hello()\n"; }
    
  3. 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関数の使用は既に行われています。覆われています。

于 2013-10-26T19:00:12.057 に答える
2

名前空間を使用する必要があります:

_

:

namespace mynamespace {
  void hello(); 
}

f.cpp

void mynamespace::hello()
{
    /... function definition here
}

main()

int main()
{
   mynamespace :: hello();   // calls hello defined in f.cpp
}

名前空間の入門として最適です。名前空間

于 2013-10-26T19:06:33.953 に答える