上一篇中已经讲到,通过c++的赋值兼容规则,public方式的派生类对象的地址是可以直接赋值给基类类型指针的。那么如果我不利用c++的赋值兼容规则,而是通过将public派生类对象地址强制转换为基类指针后赋值给基类指针变量会是怎么样的一个结果呢?
例如:
#include "stdafx.h"
#include <iostream>
using namespace std;
class CObject
{
public:
virtual void Searialize() {
cout << "Object::Serialize() \n" << endl;
}
};
class CDocument : public CObject
{
public:
virtual void Searialize() {
cout << "CDocument::Serialize() \n" << endl;
}
};
class CMyDoc : public CDocument
{
public:
virtual void Searialize() {
cout << "CMyDoc::Serialize() \n" << endl;
}
};
int main()
{
CMyDoc mydoc;
CDocument *p_document = NULL;
CDocument *p_cast_document = NULL;
p_document = &mydoc; -----利用c++赋值兼容规则,不需要做任何转换,编译器也认为是合法的赋值。
p_cast_document = (CDocument*) (&mydoc); -----利用强制转换原则,强制将CMyDoc类型指针转换为CDocument类型。
p_document->Searialize();
p_cast_document->Searialize();
}
那么p_document->Searialize()和p_cast_document->Searialize();的调用结果是一样的吗?
答案是一样的,都是 CMydoc::Serialize()
为什么结果都一样呢,通过基类指针都是调用的派生类CMdoc中的方法呢?
p_document->Searialize();就不用说了,因为它的用法是完全按照C++多态的用法来的,自然就是多态的效果了;
而p_cast_document->Searialize();呢,并没有完全按照多态的使用步骤,但是却也是多态的效果。
因为强制转换赋值的时候也是地址传递,通过调试可知p_document和p_cast_document 的值相同,都为mydoc实例的地址。所以p_document中的虚函数指针其实就是mydoc实例中的,所以通过该虚函数指针调用func()就是调用到CMydoc::Serialize()。