免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6336 | 回复: 16
打印 上一主题 下一主题

[C++] operator ->* 问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-19 10:53 |只看该作者 |倒序浏览
难道 operator ->* 不能用于成员函数指针吗?

翻了下 ISO C++ 标准,发现 operator ->* 是这样定义的:


难道它只能用于数据成员指针吗?

论坛徽章:
0
2 [报告]
发表于 2009-08-19 11:53 |只看该作者
operator ->* 不能用于成员函数指针

论坛徽章:
0
3 [报告]
发表于 2009-08-19 12:44 |只看该作者

回复 #2 aaaaa5aa 的帖子

难道对于成员函数指针,只能用 operator T* 来转换,然后再用 ->* 表达式吗?

那样会很乱耶……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
4 [报告]
发表于 2009-08-19 12:48 |只看该作者

回复 #1 xpycc 的帖子

这定义好,  收下了~~~

可以用于成员函数指针呀, 只是要注意优先级。

struct s {
  void f() {}
  void g() {}
};

s s;
s* ps = &s;
void (s::* pmf)() = &s::f;
ps->*pmf; // 这就引发了那个所谓的function, 返回了一个函数的引用。

要调用, 因为优先级的关系, 需要这样:
/*强制它们*/(ps->*pmf)/*先结合*/ /*再跟调用操作符*/ ();
(ps->*pmf)();

论坛徽章:
0
5 [报告]
发表于 2009-08-19 19:23 |只看该作者
原帖由 OwnWaterloo 于 2009-8-19 12:48 发表
可以用于成员函数指针呀, 只是要注意优先级。

我是说用句柄类代理时候的问题……

原帖由 OwnWaterloo 于 2009-8-19 12:48 发表
ps->*pmf; // 这就引发了那个所谓的function, 返回了一个函数的引用。

以前在 VC9 中,尝试用 typeid(ps->*pmf).name() 来查看它的类型,但是编译错误,以为这个表达式仅仅是给内部用的。

不过刚刚在 G++ 4.4.0 中试了下,发现其结果和 void (void)  是一样的,又尝试了下把 ps->*pmf 赋给 void(*)(void) 类型的变量,然而失败了,所以还是觉得这个表达式是内部使用的。

ps. 我再到 G++ 4.4.0 中试一下句柄类,兴许会有新的收获……

论坛徽章:
0
6 [报告]
发表于 2009-08-19 19:54 |只看该作者
果然,在 G++ 4.4.0 上的结果也一样——无法用 operator->* 来处理句柄类的成员函数指针。

ps. 一直以为 C++ 把 C 的一些模糊概念都澄清了,比如 *p = 1 这样的东西,就很模糊。直到 C++ 引入了引用概念,*p 的类型才变得清晰起来。可惜 C++ 虽然追求更好的类型系统,内部也出现了这样的不和谐(至少不广泛可用)的东西。真希望 C++ 0x 的标准快点出来,把包括左右值引用在内的一些细节做得更完美些……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
7 [报告]
发表于 2009-08-19 20:25 |只看该作者
你要了解C++的苦衷嘛……

首先,你要知道operator->*是个什么操作。所有的基本操作符都是”产生式”或者“变化式”的操作符,换言之,是由左操作数和右操作数合起来,产生一个新的值,或者是左操作数被右操作数改变,然后返回左操作数的值。而->*不一样,它是一个“绑定”值。比如说函数指针。单独一个“指向类成员函数”的指针可以直接使用么?不行,因为少了一个this指针参数的指定。少一个参数,怎么调用呢?而->*就将左操作数的参数作为类型指针“绑定”到右操作数的指针上,形成一个所谓的“闭包“。如果C++支持闭包,那么自然毫无关系,但是很可惜,于是这个闭包必须马上使用,不能存放(什么内部类型可以同时存放两个指针呢?)虽然同为void(*)(void);,但是前者是一个void(*)(void);,后者是void(*)(T const*); + T*,自然无法相互赋值。

另外*p没什么模糊的,取盒子里面的蛋糕,仅此而已,十分清晰。

论坛徽章:
0
8 [报告]
发表于 2009-08-19 21:26 |只看该作者

回复 #7 starwing83 的帖子

你的论据正好说明了应用于成员函数指针的 ->* 在 C++ 的类型系统中产生了矛盾。的确,C++ 为了语言系统的统一,没有使用闭包,因为在别的地方也没有使用。
这或许是个硬伤,不过还好这对语言的应用几乎没有影响。

*p 是什么类型对于使用是没什么关系,然而,从类型系统的角度看就不完善。

ps. 既然 C++0x 一度有可能加入匿名函数,那么闭包应该也不是障碍吧。当然仅仅是我美好的愿望罢了。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
9 [报告]
发表于 2009-08-19 21:46 |只看该作者

回复 #8 xpycc 的帖子

这漏洞从C时代就开始了:

void (*f)(void)  = 0;
*f;  代表什么? 可以用什么类型的变量存储 *f; 的值吗?  不能
*f  只能立马调用, 不能存储。
(*f)();
或者, 简单的形式 f();


函数是一段代码, 通常还不可改变。
函数指针只能指向这段代码的入口。
解引用函数, “复制”函数, 没有特别直观的意义。

int* pi;
int i = *pi; // 编译器i占用多大空间, 需要从pi复制多少

void (*p)(void);
*p; // 多大?   说不清楚。


函数指针和数据指针向来都是被区别对待的, 因为数据和代码确实异性多于共性。
指针只是表达了它们的共性: 拥有一个地址。
也能表达数据的特性: 可写,可复制。
但函数通常是不可写的, 复制时, 也不能根据一个函数类型(签名)得到该函数体的大小。
指针在表达它们的异性时, 出现了一些差异。


如果算做“类型系统不完整”, 有点钻了  类型系统也是有直观含义的, 而复制函数没有特别直观的含义。

[ 本帖最后由 OwnWaterloo 于 2009-8-19 21:51 编辑 ]

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
10 [报告]
发表于 2009-08-19 21:47 |只看该作者
闭包本来就很简单,一个指针加一个结构体就OK,只是没啥用处,因为需要的时候可以自己写。

其实觉得函数对象就是闭包了,这个只不过是“内建类型”的闭包。

换言之,其实我们观点统一。我一直认为C++的类型系统不完备。因为区别了内部类型和复杂类型了,而且区别得毫无道理(相对于python,ruby这种),因此有很多生硬的语法,这个闭包的问题恰恰就是这种问题的应用层次的表现。

所以自己写程序,纯C多些,当然C++还是比Java这种东西好多了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP