多态是面向对象中最重要的特性。在C++中多态的实现是通过带有虚函数的基类的指针或引用绑定到派生类的对象上来体现的。
如果反过来,派生类的指针或引用绑定到积累的对象上有会有什么结果呢?首先这种做法很可能是没有实际意义的,但是编译却能通过(至少在VS2012下能过)。下面通过一个例子来看看运行结果:
class base {
public:
base(int x) : a(x) {}
virtual void fcn() {
cout << "base" << endl;
}
int a;
};
class derived : public base {
public:
derived(int x) : base(x), a(x), b(x) {}
virtual void fcn() {
cout << "derived" << endl;
}
int a;
int b;
};
int main() {
base *pb = new base(100);
pb->fcn();
derived *pd = (derived *)pb; //派生类的指针绑定到基类的对象上
pd->fcn();
cout << pb->a << endl;
cout << pd->a << endl;
cout << pd->b << endl;
system("pause");
};
运行结果:
派生类指针pd指向的对象本质上还是基类的对象,内存空间中只包含基类的成员变量。两次调用虚函数都是基类的。
pd->a;pd->b;对于这两句,编译器会按照派生类中的a,b变量的偏移地址去访问,但实际上基类对象内存中并没有在此偏移位置上构造a,b,所以打印的结果是随机的。