多继承指针转化的问题

多继承的指针转化跟数据在内存的布局有极大的关系。目前,用msvc11和gcc4.8.3去测试指针转化之后的结果。发现只要不涉及编译增加虚表指针的情况下,派生类的地址多数是和继承列表的首个父类地址相同。当然会有其他问题影响到布局的指针转化。此次要提的内容是,别使用c_style指针转化。正确的指针转化来自于:dynamic_cast/static_cast。

编译器内部生成的指针对象有某个反射机制,能从父类指针正确的映射出派生类地址。无论是普通继承还是virtual继承。具体的内存布局我还要看完书才行,待续。

编译器的实现真是太有学问啦,同时也影响着我们使用这门语言。为了未来几十年能在游戏引擎有所作为,必须吃透C++/C、数学和计算机图形学应用方向等。

#include <cstdio>
#include <iostream>
#include <string>
#include <cstdarg>

class A
{
public:
	A()
	{
		i = 10;
	};
	~A(){};
	virtual void display()
	{

	}
	int i;
};

class B
{
public:
	virtual void display()
	{

	}
	int j;
};

class C :public A,public B
{
public:
	int i;
	int k;
private:

};

class D:virtual public A
{
public:
	int di;
	virtual void display() override
	{

	}
private:

};

class  E :virtual public A
{
public:
	int ei;
	virtual void display() override
	{

	}

private:

};

class F : public D,public E
{
public:
	int fi;

	virtual void display() override
	{

	}

private:

};

int main(int argv, char **argc)
{

	C * pC = new C();
	B * pB = dynamic_cast<B*>(pC);
	A * pA = dynamic_cast<A*>(pC);
	B * pB_s = static_cast<B*>(pC);
	A * pA_s = static_cast<A*>(pC);
	C * pCB_D = dynamic_cast<C*>(pB);
	C * pCA_D = dynamic_cast<C*>(pA);
	C * pCB_S = static_cast<C*>(pB);
	C * pCA_S = static_cast<C*>(pA);

	pC->i = 100;
	printf("%d\n",pA->i);

	printf("pC = %d,pB_d = %d,pA_d = %d,pB_s = %d,pA_s = %d\n", pC, pB, pA, pB_s, pA_s);

	printf("pCB_D = %d,pCA_D = %d,pCB_S = %d,pCA_S = %d\n", pCB_D, pCA_D, pCB_S, pCA_S);

	F * pF = new F();

	D * pD = dynamic_cast<D*>(pF);
	E * pE = dynamic_cast<E*>(pF);
	D * pD_s = static_cast<D*>(pF);
	E * pE_s = static_cast<E*>(pF);

	F * pFD_D = dynamic_cast<F*>(pD);
	F * pFE_D = dynamic_cast<F*>(pE);
	F * pFD_S = static_cast<F*>(pD);
	F * pFE_S = static_cast<F*>(pE);

	printf("pF = %d,pD_d = %d,pE_d = %d,pD_s = %d,pE_s = %d\n", pF, pD, pE, pD_s, pE_s);

	printf("pFD_D = %d, pFE_D = %d,pFD_S = %d, pFE_S = %d\n", pFD_D, pFE_D, pFD_S, pFE_S);

	return 0;
}
时间: 2024-11-03 21:33:38

多继承指针转化的问题的相关文章

指针转化(二重)

很尴尬 void funTest(releA**ppa) { return; } baseA test; baseA* p = &test; baseA** pp = &p; funTest((releA**)pp); 二重指针之间转化,可以直接通过(classType**)转化 基类转派生类:static_cast(最好在debug下用dynamic_cast检查一下) 派生类转基类:隐式转化 原文地址:https://www.cnblogs.com/likemao/p/9419061.

腾讯2011一道父类指针和子类指针转化的题目

class ClassA { public: virtual ~ClassA(){} virtual void FunctionA(){} }; class ClassB { public: virtual void FunctionB(){} }; class ClassC :public ClassA , public ClassB { }; 关于pA,pB,pC的取值,下面的描述中正确的是: A.pA,pB,pC的取值相同. B.pC=pA+pB C.pA,pB不相同 D.pC不等于pA也

如何具体分配一大块堆内存中的各个部分、如何指针转化为地址、如何求指针间地址偏移量(谈谈最近遇到的一个坑爹的接口需求)

最近遇到一个坑爹的接口需求 其需求简单讲,就是要我传递一个头结构体USERCERTTABLE,一个用户(USER)结构体数组,一个证书(CERT)结构体数组-- 讲道理,这样写就好了嘛Write_User_Cert(struct* head p1,struct* user p2. struct* cert p3); 不就是传递三个指针嘛 但是人家要求,参数只传递一个头结构体,然后在头结构体里写用户结构体数组的偏移量,和证书结构体数组的偏移量,然后接口只传USERCERTTABLE一个结构体作为参

C++闭包到C函数指针转化

#include <iostream>#include <memory>#include <functional>#include <cassert> // Raw Bind - simulating auto storage behavior for static storage datatemplate <typename BindFunctor, typename FuncWrapper> class scoped_raw_bind{pub

Chromium和WebKit的智能指针实现原理分析

C++不像Java一样,由虚拟机负责对象分配和释放.也就是说,开发人员使用C++编写代码时,要自己负责对象分配和释放.WebKit和Chromium都是使用C++开发的,因此它们也面临上述问题.在解决对象释放问题时,要做到在对象不需要时自动释放,因为手动释放会带来忘记释放或者释放后又继续使用的隐患.智能指针是实现对象自动释放的有效技术手段.本文就分析Chromium和WebKit的智能指针的实现. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 在现实中,

常量指针,指针常量,C++类型转换[转]

一.const应用 1.const关键字,他后面内容的不可修改,一般来说,其修饰的变量不可再进行赋值操作: 2.常量指针 int a = 3: int b = 4: const int* pt = &a: a = 5: *pt的值为5,pt只是一个指针,所以他指向的是a的内容,const限制的是*pt,所以,只是不能通过*pt修改其指向的内存内容. 3.指针常量:int* const a = pt;由于不可再进行赋值操作,所以指针常量在声明时必须赋值: 相关文章: 一.常指针与指针常量的区别?

类的成员函数指针(比較深入)

From:http://blog.csdn.net/hairetz/archive/2009/05/06/4153252.aspx 个人感觉对于类的成员函数指针这块解说的比較深入具体 推荐阅读 ///////////////////////////////////////////////// 先看这样一段代码 class test {    public:       test(int i){ m_i=i;}       test(){} void hello()       {        

C++继承分析

面向对象的三大特性之一就是继承,继承运行我么重用基类中已经存在的内容,这样就简化了代码的编写工作.继承中有三种继承方式即:public protected private,这三种方式规定了不同的访问权限,这些权限的检查由编译器在语法检查阶段进行,不参与生成最终的机器码,所以在这里不对这三中权限进行讨论,一下的内容都是采用的共有继承. 单继承 首先看下面的代码: class CParent { public: CParent(){ printf("CParent()\n"); } ~CP

C/C++之类型强制转化

强制转化四种类型可能很多人都常常忽略就象我一样,但是有时还是比较有用的.不了解的建议看看,一些机制我也不是十分了解,只是将一些用法写出来让大家看看.                                                             2004-11-27 9:00 强制转化无论从语法还是语意上看,都是c++中最难看的特征之一.但是基于c风格的转化的语义的不明确性及其一些潜在问题.强制类型转化最终还是被c++接受了. 1.static_cast运算符号stati