2011-07-21 7 views
1

派生オブジェクトを保持しているベースポインタは、引き続きベース関数を指すことができますか?基本機能は、仮想されていた場合はここで ベースポインタの派生オブジェクトがベース関数を呼び出す方法は?

a_ptr = &b_obj; 
a_ptr->disp(); 

後、私はここに派生オブジェクトが基底関数を呼び出すために管理することができますベースポインタhodlingをfunction.Butベースにするアドレスを保持しているV-テーブルの関与を、理解しています。

シーンの後ろに何が起こるのか誰にでも光を投げることができますか?

class A 
{ 
public: 
//virtual void disp() 
void disp() 
{ cout<< "From class A\n" << endl; } 
}; 

class B : public A 
{ 
public: 
void disp() 
{ cout << "From Class B\n" <<endl; } 
}; 

int main() 
{ 
A a_obj; 
A *a_ptr; 

B b_obj; 

a_ptr = &a_obj; 
a_ptr->disp(); 

a_ptr = &b_obj; 
a_ptr->disp(); 
} 

答えて

5

ベースポインタは、常に派生オブジェクトのベース部分を指します。派生オブジェクトのメンバー/メソッドに関する情報は知られていません。

A::disp()virtualと宣言すると、実行時に解決されます。 a_ptrが指すオブジェクトに基づいてA::disp()またはB::disp()を呼び出すことがあります。簡単な言葉で

  1. あなたがメソッドvirtualを宣言した場合、コンパイラは、この メソッドが実行時に評価されなければならないことを知っています。また、メソッドはポインタまたは参照を使用して呼び出さなければなりません。
  2. メソッドがオブジェクトを使用して呼び出された場合、またはメソッドが virtualでない場合、コンパイラはすぐに呼び出し元の静的タイプ のメソッドに呼び出しを行います。

あなたのケースでは、発信者の静的タイプはA*であり、方法はvirtualではありません。コンパイラはすぐにA::disp()の呼び出しを入れて、ランタイム評価を待つことはありません。

a_ptr = &b_obj; // static type --> typeof(*a_ptr) --> A 
       // dynamic type --> typeof(b_obj) --> B 
a_ptr->disp(); // (is A::disp() virtual)? 
       // chooses B::disp() at runtime : chooses A::disp() at compiletime; 

[注:あなたが唯一のB::disp()virtualとしてを作成し、それがあるとしてA::disp()通常の方法を続ければあなたが今得ているとして、あなたはまだ同じ結果を得ることができますと仮定します。]

関連する問題