c++虚函数静态关联

来源:百度知道 编辑:UC知道 时间:2024/05/22 14:53:04
#include <iostream.h>
class A{
public:
virtual void disp(){cout<<"A"<<endl;}
};
class B:public A
{void disp(){cout<<"B"<<endl;}
};
void p1(A a2){a2.disp();}
void main()
{B b;
p1(b);}

使用了虚函数,但为什么输出不为B为A,书上讲的时候都说只有指针和引用才能动态关联,输出就为B
请问为什么使用对象调用,怎么就静态关联产生答案A了?
我是讲B的对象b传递给了a2了,出来答案应该是B啊?请讲解

这个是C++中的slice现象,b是B类型的,但函数接受的是A类型的对象,所以,b被切成了A类型的,所以调用a2.disp();时,输出A;这和虚函数没有关系,虚函数通常都是和指针关联在一起的,你把代码改成这样,就会体会到虚函数了。

#include <iostream>
using namespace std;
class A{
public:
virtual void disp(){cout<<"A"<<endl;}
};
class B:public A
{
void disp(){cout<<"B"<<endl;}
};

void p1(A* a2)
{
a2->disp();
}

int main()
{
B b;
p1((A*)&b);
}

考,上面的真快啊。不过回答的不全对噢。

调用p1(b);也就是值传递,值传递是申请一个临时变量(在其构造过程中构造了一个新的vtable指针,b的vtable指针根本无法影响到它,仅仅是把b的成员变量的值赋给临时变量对象而已),然后将vtbl、成员变量压栈,再调用函数的。
所以说,值传递产生的vtable指针无法继承,故不能产生lz所要求的情况。

如果要实现动态构建必须保证b的vtable保留在参数变量对象里面,可以通过指针或者引用来实现,比如
函数定义:
p1(A & a2);
或者:
p1(A*);调用时候 p1(&b)即可,并不需要ls所说的p1((A*)&b)来强行修改。

传值是不行的 虚机制 发生的条件是 1:基类指针指向派生类对象(也就是说要传指针或引用) 2:有虚机制Virtual
所谓虚机制就是 在声明Virtual时在产生一个Table表,在运行时,根据偏移量找到正确的调用入口地址 在传值情况下只会是发