8

私は仮想メソッドと vtables の概念を理解していると思いますが、オブジェクトをポインター (または参照) として渡すことと、値で渡すこと (どのような種類の vtable などを破棄するのか?) に違いがある理由がわかりません。

なぜこのようなものが機能するのですか:

Material* m = new Texture;
poly->setMaterial(m); 
// methods from Texture are called if I keep carrying the pointer around

そして、これではありませんか?:

Material m = Texture();
poly->setMaterial(m);
// methods from Material are called if I pass the value around
4

7 に答える 7

3

仮想関数は、両方の例で完全に機能します。それらは、機能するはずのとおりに正確に機能します。

仮想関数の全体的な考え方は、そのような関数への呼び出しが、呼び出しで使用されるオブジェクトの動的な型に従ってディスパッチされるということです。(残念ながら、これらの呼び出しを行う方法を例で示していませんでした。)

最初の例では、 type のオブジェクトを作成しましたTexture。オブジェクトの動的タイプはTextureであるため、仮想呼び出しは のメソッドに行きますTexture

2 番目のケースでは、タイプ のオブジェクトを作成しますMaterial。オブジェクトの動的タイプはMaterialであるため、仮想呼び出しは のメソッドに行きますMaterial

それだけです。すべてが期待どおりに機能します。あなたの期待がこれと異なる場合は、それらを言語とよりよく一致させる必要があります.

于 2011-04-28T15:33:30.097 に答える
1
class Base
{
    //Members       
};

class Derived1:public Base
{
    //Members
};

int main()
{
    Base obj1;
    Derived1 obj2;

    obj1 = obj2;   //Allowed Since Public Inheritance 
}

obj1 = obj2基本クラスから継承された派生クラス obj2 のメンバーのみが obj1 にコピーされると、派生クラスの残りのメンバーは切り捨てられます。これは単純に、基本クラス obj1 が派生クラスのメンバーを認識していないためです。この現象は と呼ばれObject Slicingます。

あなたの場合、呼び出しMaterial m = Texture()にはのメンバーのみが含まれているMaterialため、オブジェクトの関数呼び出しはMaterial& notのメンバー関数を呼び出しますTexture

于 2011-04-28T15:38:48.587 に答える