漫谈cup,硬盘电源接口四个指针,内存和指针的关系

今天做一个成绩管理系统的并发引擎,用Qt做的,仿照QtConcurrent搞了个模板基类。这里为了隐藏细节,隔离变化,把并发的东西全部包含在模板基类中。子类只需注册需要并发执行的入口函数即可在单独线程中执行。最终目标是,继承的业务逻辑类外部调用时有两个接口可选,调用syncRun同步执行;调用由引擎自动生成的asyncRun就异步执行。最终自动生成asyncRun的模板基类没能实现,主要原因是mingw对this处理的太有问题了!!原本以为编译器问题,后来才知道成员函数指针和this指针如此特殊,对此篇文章反感者请移步文章末尾直接看好文。

\brief 汇集了各种成员函数指针的错误用法
 
 
 
 
 /* 错误的类型转换,拜一篇烂文所赐用上的 */
 
 
 (this->*ut.to)(0); //错误调用,用父类指针,以成员函数指针方式调用子类的成员函数
 
 /* 微软运行时库检测到运行时错误 */
 ut.to2(this, 1); //错误调用,用C语言风格的函数指针,直接把this作为第一个参数传入调用子类的成员函数
 
 /* 错误的类型转换,拜一篇烂文所赐用上的 */
 
 
 void *childFuncPtr; //错误使用,由于长度可能不同,void*不可以用来保存任意成员函数地址
 
 
 /* 错误的类型转换,拜一篇烂文所赐用上的 */
 
 
 
 /* 微软运行时库检测到运行时错误 */
 ut.to2(this, 4); //错误调用,用C语言风格的函数指针,直接把this作为第一个参数传入调用子类的成员函数
 
 
 
 

本例旨在测试各编译器对this的处理情况,其中有错误用法,请勿在实际项目中仿照使用!测试平台Win7x64,各编译器使用默认参数

的运行结果与vs2010几乎完全一样,debug版本一样有运行时错误,可见是微软的运行时库在起作用。但是release版本直接崩溃,也许跟优化方式有关?微软自家编译器链自家库确实有优势,呵呵~同样,去掉两处C风格调用,this指针完全正常。

总结:最费解的是mingw的结果(同学linux下用gcc测试结果一样)。父类与子类有同样的this值,同样的函数地址,父类指针直接调用子类成员函数居然可以离谱成这样!看来,奇技淫巧最终带来的后果是各种不确定,不要尝试用父类指针调用子类成员函数,更不要使用C语言的函数指针强制传递this指针!!

后续:现在才明白,我是试图用模板实现自动类型推导的委托-_-! 推荐3篇该方面的好文:

首先,你要明白一个概念,指针,是做什么的?答案是,指针,是指向地址的。

程序指针,指向的空间,在物理上是Flash,在逻辑上,就是代码空间。比如说51单片机的PC指针,指向的就是Flash,即程序下一步要执行的指令的地址。

数据指针,指向的空间,在物理上有Flash和RAM,在逻辑上是Flash里的常数空间和数据空间,注意,是对于单片机来说,对于我们的电脑,常数空间不是在Flash上。

比如说51单片机的DPTR,如果用MOVC A,@A+DPTR,此时,就是指向常数空间,如果用

堆栈指针,指向的空间,在物理上是RAM,在逻辑上,就是数据空间,是特定的数据空间,堆栈是数据空间中单独划分出来,专门用于寄存中间结果的内存空间。

数据指针和堆栈指针主要有两个区别:

一是数据指针可以指向Flash,即可以指向常数,比如说我们定义一个数组 unsigned char code Table[99],此时,就是DPTR可以指向常数空间。堆栈指针是不可以的,只能是指向RAM。

第二个区别,堆栈指针指向的是特定的数据空间,这个特定的数据空间,是从整个数据空间里划分出来,专门用于作堆栈用的,堆栈区间一旦划分出来,堆栈指针在规则上,就只能在这个范围内活动,如果出了这个范围,可能导致整个程序的崩溃。而数据指针在规则上,可以指向整个数据空间,但是,可以读堆栈空间,不应该去修改,否则也可能导致程序的崩溃。

我要回帖

更多关于 硬盘电源接口四个指针 的文章

 

随机推荐