2012-02-28 23 views
13
class Base 
{ 
    public: 
    virtual void func() const 
    { 
    cout<<"This is constant base "<<endl; 
    } 
}; 

class Derived : public Base 
{ 
    public: 
    virtual void func() 
    { 
    cout<<"This is non constant derived "<<endl; 
    } 
}; 


int main() 
{ 
    Base *d = new Derived(); 
    d->func(); 
    delete d; 

    return 0; 
} 

「これは定数ベースです」という出力が表示されるのはなぜですか。しかし、func()の基本バージョンでconstを削除した場合、これは "これは定数ではありません"という文字を出力します仮想関数const vs仮想関数non-const

d-> func()はBase func ?

+0

可能な複製http://stackoverflow.com/questions/7504300、http://stackoverflow.com/questions/3827374、およびhttp://stackoverflow.com/questions/4152799 –

+0

[派生クラスのconstではなく、基本クラスのconstである仮想関数]の重複可能性があります(http://stackoverflow.com/questions/7504300/virtual-function-that-is-const-in-the-base- class-and-not-const-in-the-derived) –

答えて

28
virtual void func() const //in Base 
virtual void func()  //in Derived 

const部分は派生クラスが基本クラスの関数をオーバーライド新しい関数ではなくを定義する手段関数シグネチャの実際一部あります。彼らの署名が一致しないからです。あなたがconst一部を除去

は、その後、彼らの署名が一致し、その後、コンパイラは、実行時の型の場合、したがって、派生クラスの関数が呼び出され、基本クラスの機能funcfuncとしてオーバーライドされたバージョン、の派生クラス定義を見てオブジェクトはDerivedタイプです。この動作は、ランタイムポリモーフィズムと呼ばれます。

+0

私はここで混乱しています。両方が2つの異なる関数として扱われている場合、ここで適用できるconstはないので、d-> func()は派生バージョンを呼び出します。 – vamsi

+1

そして実際には、あるクラスが2つの同一の関数を定義することは非常に一般的です。一つは 'const'、もう一つは' const'です。 –

+2

@vamsiでは、 'Base'の定義には1つの関数しか含まれていないので、それが呼び出されます。 –

3

いいえ、virtual void func()virtual void func() constのオーバーライドではありません。

4

virtual void func()は実際にはvirtual void func() constとは異なる署名です。したがって、元の読み取り専用の基底関数をオーバーライドしませんでした。 Derivedではなく、新しい仮想関数を作成することになりました。

メンバー関数(PTMF)へのポインタを作成しようとするとこれについてもっと知ることもできますが、それはまれな必要性です(しかし、学習や実習には良いかもしれません)。

C++ 11のoverrideキーワードは、この種の間違いを避けるために特に便利です。コンパイラは、派生関数の 'func'の定義が何も上書きしないことを伝えます。