| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1811 人关注过本帖
标题:为什么reinterpret_cast也不能进行强制转换 ?
只看楼主 加入收藏
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
结帖率:79.17%
收藏
已结贴  问题点数:10 回复次数:10 
为什么reinterpret_cast也不能进行强制转换 ?
对于
class TestClass {
public:
       void classFn2(void) { printf("classFn2\n"); }
} classTmp;

typedef void (__cdecl * VPF)(void);
VPF tt ;
不管使用
void *tt = (char*)classTmp.classFn2;  // failed
或者
#define TTT( a , b ) (a)=(b)
或者
unsigned int aaa = reinterpret_cast < unsigned int & > classTmp.classFn2;
以及memcpy( tt,(void*)classTmp.classFn2,4);,为什么一个都不能进行强制的复制呢?
搜索更多相关主题的帖子: cast reinterpret 
2010-08-06 23:11
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
D:\Program_Files\Microsoft Visual Studio\MyProjects\test\testStub.cpp(130) : error C2440: 'type cast' : cannot convert from 'void (__thiscall TestClass::*)(void)' to 'unsigned long'
        Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-09 23:50
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:10 
gcc 给的提示是
error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say ‘&TestClass::classFn2’

不过我从来没这么写过代码。呵呵,属于诡异的用法吧~ 有空我研究研究吧,看看标准是怎么说的。


__cdecl 这个关键字以前经常在 VC 里看见,有什么用吗?
2010-08-10 01:45
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
还真没在在标准上找到禁止这么写的相关说明。不过涉及强制转换的主题比较广,标准并不是集中描述的,而是分散在各个章节,所以很难查。

要是想干相同的事,还是老老实实地用指向成员函数的指针吧~
其实不能这么写倒是可以理解,因为毕竟不是每个实例都拥有成员函数的定义,而是类定义拥有的。类实例在调用的时候,是把 this 指针做为附加参数传给类中定义的成员函数。所以当时我看代码的时候,觉得 classTmp.classFn2 这种写法本身就有问题。只不过编译器给的报错和我想的很不一样……

成员函数指针这种語法其实也算比较生僻了,我介绍一下吧,难得有人问这么有意思的问题,就当给大家扩充一个知识。
像你这个类的话,就是这样:
void (TestClass::*t)(void) = &TestClass::classFn2   // 直接指向类的函数定义。
调用的时候,通过要经过类实例:
(classTmp.*t)();

这种語法倒是偶尔能看见,不过我觉得也不常用。
C 语言里的函数指针一般比如说用于回调函数的呀,在 C++ 里都可以用函数对象来代替(函数对象 Function object,有时也叫 Functor)。与此同时就可以获得好多强大的能力,比如更丰富的类型转换,重载等等。当然还有特殊的用法,比如绑定参数什么的。

C++ 的语法确实比较复杂,有的时候想的太深容易被绊住。所以遇到问题的时候问一问还是好的,不过用的时候还是应该选择自己熟悉的方法。当 C++ 的语法不能提供灵活与方便时,其实就是个累赘。
2010-08-10 08:35
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 3楼 pangding
__cdecl  指明参数压栈的顺序

__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参 数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-10 22:32
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
哦,就是C式调用的意思,类似这个的东西只在汇编时用过。你不说可变参数还真没注意过。
2010-08-11 02:03
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
以下是引用pangding在2010-8-10 01:45:20的发言:

gcc 给的提示是

不过我从来没这么写过代码。呵呵,属于诡异的用法吧~ 有空我研究研究吧,看看标准是怎么说的。


__cdecl 这个关键字以前经常在 VC 里看见,有什么用吗?
您研究的怎么样了?分享下吧 呵呵

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-14 12:41
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
基本上 4 楼的就是研究之后的。标准里没找到相关的说法。
看来 gcc 没实现了的,就说是标准不让~~


我的建议就是别这么弄,你有什么特别的理由要这写吗?如果有我觉得就是设计不当,你可以说说看,我帮你分析分析是不是有更好的写法。


2010-08-15 15:17
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
以下是引用pangding在2010-8-15 15:17:00的发言:

基本上 4 楼的就是研究之后的。标准里没找到相关的说法。
看来 gcc 没实现了的,就说是标准不让~~


我的建议就是别这么弄,你有什么特别的理由要这写吗?如果有我觉得就是设计不当,你可以说说看,我帮你分析分析是不是有更好的写法。
我只是想得到成员变量classTmp.classFn2 的地址而已,不知道有什么好方法?

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-16 01:30
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
不知道有什么好方法能。
类成员函数的地址一般都是靠什么地址表这类方法的转过去的,实现的机理虽然不太复杂,但是跟一般想像是肯定是不一样。不让用我觉得挺正常的,而且虽然非静态的数据成员是每个对象都自己拿着有,但函数成员不管静态与否,都是共用一个。受虚函数,多态等各种行为的影响,调用过程也相对复杂,应该是你拿了那个地址,也不能作入口用,编译器无法控制这种行为。连 void* 都接不了这个地址,肯定是有原因的。
这个复杂性,和常对象的控制差不多,但是还更复杂一点。常对象是靠常成员函数的特殊語法机制,在编译阶段控制的。因为运行时几乎无法有效的审核。这个函数地址我想也一样,肯定没有什么运行时的有效机制审核,所以只能用我 4 楼的那种語法机制控制。当然另一个原因,我在 4 楼也提了,就是函数指针这种語法能发挥的功效,很多在 C++ 里都有其它更好的方式能做。用到的概率非常低了。就像有了内联函数之后,带参宏基本就没用了一样。
2010-08-16 12:10
快速回复:为什么reinterpret_cast也不能进行强制转换 ?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035972 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved