2017-06-22 8 views
0

なぜこれはコンパイルされませんか?宣言し、クラスメソッドを定義する - なぜエラー?

class Test 
{ 
    void foo(); 
    void foo() 
    { } 
}; 

しかし、これらはコンパイルします:

void bar(); 
void bar() 
{ } 

// In same header/file 
class Test 
{ 
    void foo(); 
}; 
void Test::foo() 
{ } 

をコンパイラがその与えられた方法cannot be overloadedと言うでしょう。メソッドTest::fooはオーバーロードされていません。これは全く同じシグネチャを持つ同じ関数です。

+0

@StoryTeller ^答えが必要です:) – Curious

+1

各メンバーは、クラス内で一度だけ宣言する必要があります。各定義は宣言でもあります。 –

+0

@StoryTeller良い答えは標準的な見積もりを必要としません!特にこのようなもののために。 – Curious

答えて

5

C++標準では明示的に禁止されています。それは、インラインメンバ関数である、またはそれが既に宣言されている場合、そのクラス定義 の外部で定義されてもよい 場合た、そのクラス定義で右が[class.mfct/1]

メンバ関数で定義されてもよいが、そのクラス定義には が定義されていません。 がクラス定義の外に出現するメンバ関数定義は、クラス定義を囲む名前空間スコープ に現れなければならない。 、およびクラステンプレートとメンバ 関数テンプレートのメンバ関数の明示的な 特殊を除くクラス定義の外側に表示されるメンバ関数定義 を除き([temp.spec])クラス 定義の外部、現れますメンバー関数を再宣言してはならない。

+0

グローバル関数の宣言/定義がまったく同じ方法で許可されているが、クラス内では許可されていない理由を述べていません。 – Ajay

+0

@Ajay - もちろん、許可されていると言われていますが、別のセクションでは**自由な機能**宣言について述べています。これは**メンバー**についてのものであり、見積もりに明示されています。 – StoryTeller

0
void foo(); 

void foo() {} 

クラス定義の関数を宣言するの2つの方法があります。最初の関数は関数を宣言し、2番目の関数は関数を宣言し、それを実装します。したがって、コンパイラは、同じ関数を再宣言することを前提としており、関数シグニチャが両方とも同じであるため、適切なオーバーロードではありません。

+0

質問には答えません。 – Ajay

1

これはC++の単なる方法です。クラスのメンバーを再宣言することはできません(クラス外の定義をと別のの宣言として考えている場合を除き、)。 ODRに従う限り、名前空間メンバーの再宣言はOKです。

+0

正当な理由があります。 'T x()'はコンストラクタを呼び出すのではなく、関数宣言を呼び出します.C++コンパイラはまずC言語のルールを考慮する必要があるからです。同様に、ODRルールは、フリーとクラス・レベルの機能で異なることはできません。 – Ajay

1

なぜこれはコンパイルされませんか?

class Test { 
    void foo(); 
    void foo() { }; // wrong 
}; 

StoryTellerと他の人が答えとして、あなたは宣言と定義同じメンバ関数void Test::foo(void)を二度(およびfooの内部クラスの定義は、暗黙的にinlineある)されている、ので。

あなたが後、あなたのヘッダファイルクラスのメンバ関数を定義したい場合は、あなたがより良い、このようなinlineとして明示的に宣言します:

class Test { 
    inline void foo(); 
}; 

以降のは(そのメンバ関数を定義します例えば)同じヘッダファイルにおいて以下:BTW

void Test::foo() { 
    // body of Test::foo 
} 

、あなたが外上記のように定義し、そのメンバ関数とメンバ関数を宣言した場合は、inlineではなく、いくつかの中に含まれているいくつかのヘッダファイル内定義ありますその機能は複数定義され、リンカーは文句を言うでしょう。

+1

このような場合、インライン指定子が適切なリンケージの重要性を忘れてしまうのは簡単です。 +1 – StoryTeller

+0

インラインは宣言/定義と関係がありますか?グローバル関数でも同じことができますが、クラスメソッドではできません。どうして?また、 'inline'属性がフリー関数に適用されても、それでもコンパイルされます。 – Ajay

+0

リンク時に問題が発生する可能性があります。 –

関連する問題