2011-01-20 22 views
1

私は、grand-parentクラスが関数XYZの純粋仮想バージョンを含む純粋仮想であるというコードを変更しています。その後、親クラスはXYSを仮想として宣言し、XYSを実装しています。次に、子クラスは、それ自体が私に混乱している親クラスの実装とは異なる実装で、XYZを通常の関数として宣言します。別のオブジェクトから関数XYZを呼び出すと、どの実装が実行されますか?親子か子供のどちらか?ありがとう純粋仮想と仮想の違い

+3

lol "grand-parent class" –

+0

子のXYZも仮想です。キーワード 'virtual'が書かれていなくても、ベースのXYZは仮想ですので、パラメータリストが同じであれば子も同じです。 –

答えて

3

純粋な仮想関数は(仮想関数ではなく)定義を必要とせず、クラスを抽象化します。抽象クラスは、基本クラスオブジェクトとして動作する場合を除いて、作成元のオブジェクトを持つことはできません。

あなたの混乱は、virtualキーワードの有無を中心にしているようです。関数が基底クラスのvirtualと宣言されている場合、virtualキーワードを付けても、派生クラスの関数は、同じ名前、パラメータ型、および定数を持つ場合、自動的にvirtualになります。

あなたが実際にchildオブジェクトを指すgrandparent*またはparent*にXYZを呼び出すのであれば、その後、childオブジェクトのXYZが実行されます。

+1

私は自分の質問のタイトルが質問の内容とは無関係であることに気付きました。できれば私の質問の内容を読んで助けてください。ありがとうございました – user553514

+0

@ user553514:Cheeky。彼はあなたの質問に答えました。 –

2

純粋仮想関数は、純粋仮想関数を持つクラスをインスタンス化できないことを意味します。親クラスがオーバーライドすると、それは通常の仮想関数になります。ファンクションが基本クラスで仮想宣言されると、継承クラスがそれを仮想として定義しているかどうかにかかわらず、常に仮想になります。

編集:これは、他の仮想関数と同じように仮想関数を呼び出すことです。つまり、最も派生したクラスの実装が呼び出されます。

+0

+1は良い答えですが、これはOPが実際に尋ねた質問ではありません。混乱して、私は知っている... –

0

通常、純粋な仮想関数は実装がなく、クラスの「抽象度」を作成します。

コンパイラは抽象クラスのインスタンスを作成させません。継承するすべての純粋仮想関数が実装されていない限り、このクラスから派生したクラスは抽象クラスのままです(新しいクラスも追加されません)。そのようなクラスはコンクリートと呼ばれます。

純粋な仮想関数に実装を与えることができます(ただし、構文上の理由からインライン化することはできません)。さらに、純粋な仮想デストラクタを持つことができますし、空の仮想デストラクタを実装しなければなりません(空の場合でも)。

あなたは、このように末尾に= 0を追加することで、純粋仮想関数を示しています

virtual void foo(); // not pure 
virtual void bar() = 0; // pure virtual 
5

を私は実装が実行されます別のオブジェクトからXYZ関数を呼び出すときは?親子か子供のどちらか?

Let's find out:

struct A { 
    virtual void f() = 0; 
}; 

struct B : A { 
    virtual void f() { cout << "B::f\n"; } 
}; 

struct C : B { 
    virtual void f() { cout << "C::f\n"; } 
}; 

int main() { 
    C().f(); 
    return 0; 
} 
0
class sample 
{ 
public: 
    virtual void fun(); //virtual function 
    virtual void sun()=0; //pure virtual function 
}; 

上記行われるように純粋仮想関数は、0を割り当てることによって宣言されます。仮想関数の定義を提供することが、それ以外の場合はないコンパイルされ、強制ありながら純粋仮想関数の定義を提供することは、オプションです。また仮想関数を定義するクラスのインスタンスを作成することはできません。

0

仮想関数は、派生クラスでオーバーライドできる関数です。

純粋な仮想関数は実装が全くないため、MUSTは派生クラスでオーバーライドする必要があります。

純粋仮想関数を使用してクラスのインスタンスを作成することはできません。独自の実装で純粋仮想関数をオーバーライドしない限り、クラスのインスタンスを作成することはできません。仮想関数の場合

0

、あなたは子クラスのオブジェクトに対してXYZを呼び出す場合、XYZ(Child::xyz())の常に子のバージョンが実行されます。

非仮想オーバーライドされたメソッドの場合はありません。そしてポインタParent* ptr = &childがある場合、ptr>xyz()は実際にParent::xyz()を実行します。しかしあなたの場合はChild::xyz()です。そのため、virtualというキーワードを使用しています。

関連する問題