2012-02-18 7 views
1

私はちょうど知りたかった 過負荷の間に関数呼び出しを行う上で決定的な要素は何ですか?私はパラメータのシグネチャを知っているので、パラメータの数は重要な役割を果たす を渡しました。しかし、オーバーロード中に重要な部分である の部分を再生するconst部分もあります。 1番目と2番目の関数のオーバーロードは正常に機能しますが、渡されたパラメータの中でconstを持つ3番目の関数 を追加すると、コンパイルエラーが発生します。 int A::sum(int, int) and int A::sum(int, int) cannot be overloaded。ただ、クラスのコードスニペットを与える:私は通常のオブジェクトを宣言し、最初の関数が呼び出されると、constオブジェクト第2の和の場合には取得し合計する呼び出しを行うと関数のオーバーロード中に呼び出されるものは何ですか?

class A 
{ 
    private: 
    int x; 
    int y; 

    public: 
    int sum (int a, int b) 
    { 
     cout << " Inside 1st "; 
     return (a+b) ; 
    } 

    int sum (int a ,int b) const 
    { 
     cout << " Inside 2nd "; 
     return (a+b) ; 
    } 

    int sum (const int a ,const int b) 
    { 
     cout << " Inside 3rd "; 
     return (a+b) ; 
    } 

    A(){x=0;y=0;} 
    ~A(){}; 
}; 

することと呼ばれています。それは完璧です。しかし、もし私が第一と第三の機能を書いたらそれは問題になります。なぜそうなのか?

+2

'void f(T);'として関数を宣言すると* void *(T const x){/ * ... * /} 'として定義することができます。言い換えれば、値パラメータのconstanceは、実装スコープ内のローカル変数のconstanceにのみ影響し、関数が*呼び出される方法とは何の関係もないため、実装の詳細です。 –

答えて

5

const -nessにオーバーロードすることはできますが、実際には違いがあります。 「実際に違いを生む」とはどういう意味ですか?さて、あなたは

void foo(char *ptr); 
void foo(const char *ptr); 

を宣言した場合const事項:あなたがfoo保証の1つの過負荷がにptrポイントというメモリを変更しないことを言っている、と他にはありません。あなたは

void foo(int x); 
void foo(const int x); 

を宣言した場合でも、const問題ではありません:fooの仮定の変化もないが、それが望んでいた場合でも、その呼び出し元にxの値を変更することができるようにスカラーの引数は常に、値によって渡されます。したがって、C++標準では、constは破棄されており、これらは同じ関数の2つの異なる宣言であり、そのうちの1つに誤りがあります。

constの位置は*です。ポインタは、スカラーそのものであるので、これらは、同じ機能の2つの宣言である:ここでconstポインタ自体ではなく、それが指すオブジェクトを修飾するため

void foo(char *ptr); 
void foo(char *const ptr); 

const修飾子をメソッド宣言の引数リストは、オブジェクトに適用された後、thisで指され、それは上でオーバーロードできます:

struct A 
{ 
    int foo (char *ptr); 
    int foo (char *ptr) const; 
    int foo (const char *ptr); 
    int foo (const char *ptr) const; 
}; 

あなたはこれらの宣言を考えなければならない方法に私たちをもたらします

struct A {}; 
int A_foo (A *this, char *ptr); 
int A_foo (const A *this, char *ptr); 
int A_foo (A *this, const char *ptr); 
int A_foo (const A *this, const char *ptr); 

となり、すべてがオーバーロードされた関数の通常の規則に従って動作します。

+0

ワンダフルな説明ザックは事実をちょうどチェックします。すべての疑問をクリアすることを願っています。 – Invictus

2

constと非const関数がオーバーロードすることができる。(constが機能した後、次の)
すなわち、それは関数のオーバーロードのために有効な条件です。

all.The関数の引数は値によって渡され、関数がコピーを受信された時に引数のconst性は重要ではありませんので、しかし、あなたの例では関数は、関数の引数のconstネスに基づいて、オーバーロードすることはできませんそれの。
関数のオーバーロードでは、の同じ名前の間にいくつかの識別基準が必要である必要があります。const引数で、実際に関数がオーバーロードされるのをコンパイラの観点から区別しない限り、関数の引数のconstを使用したオーバーロードは許可されません。あなたがconstオブジェクトを持っている場合
はその後、あなたはそれだけでconst関数を呼び出すことができ、ため

前者が可能です。非const関数はクラスメンバを修正するためにバインドされているため、それをconstオブジェクトで呼び出すと意味上のエラーとなり、コンパイルエラーが発生します。

通常のconstオブジェクトの場合は、constと非constバージョンの関数の両方がインスタンスに対して呼び出されるのに有効です。コンパイラは非constバージョンである最も適切なものを選択します。

+0

何か特別な理由はありますか?なぜコンパイラは 'const 'のパラメータに基づいてオーバーロードを実行できないのですか? – Invictus

+0

私が不思議に思っていたことや、答えるべき位置にあることは、オーバーロード/継承とアクセス制御です。私の経験によれば、fooが基本クラスで 'protected'の場合、派生クラスのfoo''''''''をオーバーロードしません。しかし、一般的なルールは何ですか? –

+0

@AlsありがとうAls、私はあなたのポイントを持っていますが、私の質問はなぜコンパイラdoesnotは私にそれで渡されたconstパラメータで3番目の関数を使用することができますか? – Invictus

関連する問題