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


首先我们来看一下下面这段代码,类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;
}

运行结果:

这里写图片描述


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值