2011-07-01 14 views
1

レム例を与えることによって、私の問題を説明します。仮想関数は継承で変わっていますか?

#include <iostream> 

class PC 
{ 
public: 
    PC():Data(0) 
    { 
    } 
    virtual void display() 
    { 
     std::cout<<"The data is :"<<Data<<std::endl; 
    } 
protected: 
    int Data; 
}; 

class SmartPC:private PC 
{ 
public: 
    SmartPC():PC() 
    { 
    } 
    void convert() 
    { 
     PC* temp=static_cast<PC*>(this); 
     temp->display(); 
    } 
    void display() 
    { 
     std::cout<<"The data is (in bb):"<<a<<std::endl; 
    } 
}; 

int main() 
{ 
    SmartPC SmrtPC; 
    PC* miniPC= static_cast<PC*>(&SmrtPC); 
    SmrtPC.convert(); 
} 

スコット・マイヤーズによると:static_cast<PC*>(this);はSmartPCの一時ベースのコピーを作成します。しかし、temp->display();は、派生クラスの関数display()を実行しました。どうしてこんなことに?オブジェクトが完全にSmartPCのベースのコピーになったので、ベースのdisplay()の機能を実行するべきではありませんか?

もう一つの問題は、私がconvert()機能で行temp->data;を追加する場合、それは PC::Dataが保護されているが、私はSmartPCすなわち、派生クラスの範囲からそれをアクセスしていますが、なぜそれが機能しないのですか?と言うことですか

何か助けていただければ幸いです。

+1

マイヤーズの言葉を引用してください。おそらくあなたは彼を誤解したでしょう。 –

答えて

5

scottマイヤーによると:static_cast<PC*>(this);は、SmartPCの一時ベースコピーを作成します。 temp->display();display()派生クラスの関数を実行したのはなぜですか?オブジェクトは完全にSmartPCのベースのコピーであるため、ベースのdisplay()の機能を実行する必要があります。

コピーは作成されません。は、ポインタをキャストしているだけです。

クラス(SmartPC *であるオブジェクトのダイナミック型に記載)関数の「正しい」バージョンを呼び出すことで、ポインタ結果介しvirtual関数を呼び出し、多型であるので。

の場合は、代わりに、displayは非virtual方法のために、それが呼ばれるようにされているバージョンを判断するために、ポインタの静的な型なので、基本クラスのバージョンは、呼ばれていたであろう、virtualませんでした。

displayが継承されvirtual機能をオーバーライドするとき、それが明示的に指定されていない場合でも、virtual修飾子が暗黙指定されSmartPCでもvirtualある)


あなたがやった場合は、その代わりに注意してください:

PC temp(*this); 

実際には現在のオブジェクトのコピーが作成され、オブジェクトとして「スライスされた」タイプPCです。これは「オブジェクトスライシング」と呼ばれ、コピーコンストラクタPCによって実行されます。多くの場合、これは望ましくない動作です(派生クラスのオブジェクトは実際に基本クラスのオブジェクトになり、多態性は期待通りに機能しないため)。


もう一つの問題は、私はconvert()機能で行temp->data;を追加する場合、それはPC::Data言うことで保護されていますが、私はSmartPCすなわち、派生クラスの範囲からそれをアクセスしていますが、なぜそれが動作しないのですか?あなたが別のオブジェクトのprivateメンバーにアクセスしようとしているtemp->dataアクセスしようとすると、概念的に

は、(それがtempが実際にthisであることは重要ではありません)ので、アクセスが拒否されます。 protectedメンバーにアクセスするための "派生クラス特権"はthisでのみ動作します。

1

これはクラスのコピーではなく、基本クラスオブジェクトへの参照であり、他のものと同じように多態的に動作します。

保護されたメンバーにアクセスできない理由は、プライベート継承を使用したためです。

+0

これを説明できますか**保護されたメンバーにアクセスできない理由は、プライベート継承**を使用したためです。派生クラスは継承がprivateかpublicかをクラスのスコープ内で保護されたメンバにアクセスできるためです。ありがとう –

関連する問題