浅谈C++指针类型的转换

来源:互联网 发布:浙江华为 知乎 编辑:程序博客网 时间:2024/06/10 19:59

首先我们来看一下下面这段代码,类C多重继承自类A和类B,观察程序运行后打印的结果我们会发现 (A*)c 和 (B*)c 的值不同,为什么做了一次强转之后的值会不一样呢?


#include "stdafx.h"#include <iostream>using namespace std;class A{public:    virtual void DrinkSomething(){};private:    int A1;    int A2;};class B{public:    virtual void EatSomething(){};private:    int B1;    int B2;};class C : public A, public B{private:    int C1;    int C2;};int _tmain(int argc, _TCHAR* argv[]){    A* a = new A();    B* b = new B();    C* c = new C();    cout << "c pointer:" << c << endl;    cout << "c pointer:" << (A*)c << endl;    cout << "c pointer:" << (B*)c << endl;    B* pB = c;    cout << "pB pointer:" << pB << endl;    A* pA = dynamic_cast<A*>(pB);    cout << "pA pointer:" << pA << endl;    cin.get();    return 0;}

原来编译器在强转的时候会根据自定义类的子类父类关系,对指针的值进行位置偏移。入下图所示。


这里写图片描述


pointerC 是一个 C 类型的指针变量,它指向一个 C 类变量的内存空间,如图中的长方体,由于 C 多重继承自 A 和 B ,所以他的内存空间由A和B两部分组成。当进行 (A*) pointerC 或者是 B* pointerB = pointerC这样的操作时,编译器就会根据内存的布局,重新定位到C类内存空间中真正指向A类内存空间的部分。


B* pB = c;cout << "pB pointer:" << pB << endl;A* pA = dynamic_cast<A*>(pB);cout << "pA pointer:" << pA << endl;

下面我们来浅谈一下dynamic_cast的用途。dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的,在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。另外,dynamic_cast还支持交叉转换(cross cast)。


#include<iostream>using namespace std;class A{public:   int m_nA;};class B{public:   int m_nB;};class C:public A,public B{public:   int m_nC;};int main(){    C *pC = new C;    cout<<"pC= "<<(int) pC<<endl;    B *pB = dynamic_cast<B*>(pC);   //a    B *pB1 = static_cast<B*>(pC);   //b    B *pB2 = pC;                    //c    cout<<"pB= "<<(int) pB<<endl;    cout<<"pB1="<<(int) pB1<<endl;    cout<<"pB2="<<(int) pB2<<endl;    return 0;}

运行结果:

这里写图片描述


分析:这是一个派生类指针向基类指针转换的例子,这种转换只是将派生类指针向下挪几个位置(挪多少与具体成员有关),即指向到基类位置的地方。因为在派生类中既包含基类成员又包含派生类成员。

原创粉丝点击