为什么虚函数需要通过指针而不是值(对象)传递?

我想我理解虚方法和 vtable 的概念,但我不明白为什么将对象作为指针(或引用)传递和按值传递(哪种废弃 vtable 或什么?)

I think I understand the concept of virtual methods and vtables, but I don't understand why there is a difference between passing the object as a pointer(or reference) and passing it by value (which kind of scraps the vtable or something?)

为什么会有这样的工作:

Why would something like this work:

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

推荐答案

因为如果按值传递,那么 会发生对象切片,无法实现运行时多态.在您的代码中,Material m = Texture() 行会导致对象切片.所以即使你通过指针(或引用)传递m,也无法实现运行时多态性.

Because if you pass by value, then object slicing will occur, and runtime polymorphism cannot be achieved. And in your code, the very line Material m = Texture() causes object slicing. So even if you pass m by pointer (or reference), runtime polymorphism cannot be achieved.

另外,运行时多态性是通过以下方式实现的:

Also, runtime polymorphism is achieved through:

  • 基本类型的指针,或
  • 基本类型的引用

因此,如果您想要运行时多态性,您可以使用基本类型的 pointer 或 reference,以下是一些如何实现运行时多态性的示例:

So if you want runtime polymorphism, you've use either pointer or reference of base type, and here are few examples how you can achieve runtime polymorphism:

Material* m1 = new Texture();
poly->setMaterial(m1);     //achieved

Texture* t1= new Texture();
poly->setMaterial(t1);     //achieved

Texture t2;
poly->setMaterial( &t2);   //achieved : notice '&'

Material & m2 =  t2;
poly->setMaterial( &m2 );  //achieved : notice '&'

Material  m3;
poly->setMaterial( &m3 );  //NOT achieved : notice '&'

只有在最后一行你没有实现运行时多态性.

Only in the last line you don't achieve runtime polymorphism.

相关文章