讨论一下 operator() 重载的大大好处 (算抛砖引玉吧)

214 views
Skip to first unread message

microcai

unread,
Apr 29, 2013, 9:35:21 PM4/29/13
to pon...@googlegroups.com

话说 C++ 语言里的一个伟大的决策就是能进行运算符重载.

而这么多运算符重载里, 最最最豪华有用便利神器的,就是 () 运算符重载了.

() 运算符重载,就能将一个对象作为一个函数, 以实现闭包.

闭包是非常有用的功能, C 语言因为不支持闭包, 必须搞个邪恶的 void* 作为回调参数之一. 而不懂得使用闭包
的人, 也会使用"单根继承" 这种恶心的策略. ( hei ,我说的是 你 ! MFC 和 Qt .) 通过基类指针来代替 void*

闭包可不简简单单的用来做 for_each 的参数, 更重要的是用来实现协程.

用闭包实现的协程, 无需一个例程用于上下文切换 (swap_context(3) 和 Win32 里的 Fiber)

所有的状态都保存在了成员变量里.

hi, 砖头出了, 欢迎玉


HaoPeiQiang

unread,
Apr 29, 2013, 11:27:13 PM4/29/13
to pongba
这属于唯恐天下不乱么?

我对C++不是很懂,欢迎大家拍砖


2013/4/30 microcai <micro...@gmail.com>




--

---
您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out





--

机械唯物主义 : linjunhalida

unread,
Apr 30, 2013, 12:07:31 AM4/30/13
to pon...@googlegroups.com
有没有示例代码展示?不是很懂。

2013/4/30 HaoPeiQiang <HaoPe...@gmail.com>



--
GuruDigger- We help internet products find technical partners who share the same dream!

- http://gurudigger.com

Fang Zhou

unread,
Apr 30, 2013, 1:12:18 AM4/30/13
to pon...@googlegroups.com
个人觉得,运算符重载带来的混乱(你永远不能一眼看出c = a + b是什么意思)远远多于它带来的好处。


2013/4/30 机械唯物主义 : linjunhalida <linjun...@gmail.com>

microcai

unread,
Apr 30, 2013, 1:42:06 AM4/30/13
to pon...@googlegroups.com
> 在 2013年4月30日 星期二 13:12:18,Fang Zhou 写道:


> 个人觉得,运算符重载带来的混乱(你永远不能一眼看出c = a + b是什么意思)远远多于它带来的好处。
>


任何语言特性滥用都是带来混乱的. 你这么认为只能说明你看到的代码滥用居多吧.


> 2013/4/30 机械唯物主义 : linjunhalida <linjun...@gmail.com[1]>


> 有没有示例代码展示?不是很懂。
>


> 2013/4/30 HaoPeiQiang <HaoPe...@gmail.com[2]>


> 这属于唯恐天下不乱么?
>


> 我对C++不是很懂,欢迎大家拍砖
>

> 2013/4/30 microcai <micro...@gmail.com[3]>


> 话说 C++ 语言里的一个伟大的决策就是能进行运算符重载.

而这么多运算符重载里, 最最最豪华有用便利神器的,就是 () 运算符重载了.

() 运算符重载,就能将一个对象作为一个函数, 以实现闭包.

闭包是非常有用的功能, C 语言因为不支持闭包, 必须搞个邪恶的 void* 作为回调参数之一. 而不懂得使用闭包
的人, 也会使用"单根继承" 这种恶心的策略. ( hei ,我说的是 你 ! MFC 和 Qt .) 通过基类指针来代替 void*

闭包可不简简单单的用来做 for_each 的参数, 更重要的是用来实现协程.

用闭包实现的协程, 无需一个例程用于上下文切换 (swap_context(3) 和 Win32 里的 Fiber)

所有的状态都保存在了成员变量里.

hi, 砖头出了, 欢迎玉


pongba+un...@googlegroups.com[4]。要查看更多选项,请访问
https://groups.google.com/groups/opt_out[5]


>

>


> --
>


> http://magazine-maker.com[6]
>


> -- --- 您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。要退订此论坛并停止接收此论

坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com[4]。要查看更多选项,请访问
https://groups.google.com/groups/opt_out。[7]

>

>


> --
> GuruDigger- We help internet products find technical partners who share the
same dream!

- http://gurudigger.com[8]

> -- --- 您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。要退订此论坛并停止接收此论

坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com[4]。要查看更多选项,请访问
https://groups.google.com/groups/opt_out。[7]

>


> -- --- 您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。要退订此论坛并停止接收此论
坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com。要查看更多选项,请访问

_https://groups.google.com/groups/opt_out。_

>


--------
[1] mailto:linjun...@gmail.com
[2] mailto:HaoPe...@gmail.com
[3] mailto:micro...@gmail.com
[4] mailto:pongba%2Bunsu...@googlegroups.com
[5] https://groups.google.com/groups/opt_out
[6] http://magazine-maker.com/
[7] https://groups.google.com/groups/opt_out
[8] http://gurudigger.com

tao

unread,
Apr 30, 2013, 2:19:51 AM4/30/13
to pon...@googlegroups.com
我觉得应该参考下《C++沉思录》和《Accelerated C++》的作者的观点:

C++的很多特性是用来开发“库”的,而不是开发“应用”的。

jack

unread,
Apr 30, 2013, 3:56:02 AM4/30/13
to pon...@googlegroups.com
运算符重载带来的是直观, 除非一帮垃圾程序员不遵循运算符的语义, 瞎重载, 这谁也没办法阻止.

Xiang Chen

unread,
Apr 30, 2013, 4:55:34 AM4/30/13
to pon...@googlegroups.com
一个矩阵乘法,用运算符要比方法直观多了。
要说造成混乱,我觉得方法和运算符没有啥本质区别,一个Add方法你非要实现成Sub的语义,谁能拿你怎样呢?


2013/4/30 Fang Zhou <ark...@gmail.com>

Fang Zhou

unread,
Apr 30, 2013, 4:55:33 AM4/30/13
to pon...@googlegroups.com
闭包那个我不太懂,但是绝大部分情况把重载运算符要做的事写成一个名字直观的成员方法是不是更好一些?


2013/4/30 jack <ja...@avplayer.org>

Yongwei Wu

unread,
Apr 30, 2013, 5:56:27 AM4/30/13
to pon...@googlegroups.com
class Matrix;

Matrix a;
Matrix b;
...
Matrix c = a + b;

可读性有任何问题吗?难道Add(a, b)或a.Add(b)读起来更好?

2013/4/30 Fang Zhou <ark...@gmail.com>



--
Wu Yongwei
URL: http://wyw.dcweb.cn/

Yongwei Wu

unread,
Apr 30, 2013, 5:58:44 AM4/30/13
to pon...@googlegroups.com
好处你说得不很明显了?这个是实现闭包所需要的。除此之外,我也没见过什么好的其他用法。

当然,现在C++11有Lambda表达式,可以减少一些重载operator()的需要了。

2013/4/30 microcai <micro...@gmail.com>
--

---
您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out


Yongwei Wu

unread,
Apr 30, 2013, 6:24:28 AM4/30/13
to pon...@googlegroups.com
网上搜索一下“functor”找到例子,比如这儿:


用“函数对象”也行,但我看了几篇,都不觉得很好。能看英文的看英文吧。

C++11的function模板可以接受函数对象,比如上面例子里的add_x,可以像下面这样传递:

std::function<int(int)> add42 = add_x(42);

然后,这个add42可以当作参数传递给其他函数,也可以像函数一样使用(如add42(3))。

2013/4/30 机械唯物主义 : linjunhalida <linjun...@gmail.com>



--

猛禽

unread,
Apr 30, 2013, 8:05:44 AM4/30/13
to pon...@googlegroups.com
至少在模板参数可以使用函数对象之前,()重载的用处我觉得还是比较有限的。
很多年不用C++,不知道现在已经可以了,大概会比以前有用一些吧。
其实运算符重载用得恰当的确是个神器,但太容易被滥用了…

在 2013年4月30日星期二UTC+8下午6时24分28秒,吴咏炜写道:

chenbo li

unread,
Apr 30, 2013, 10:03:46 AM4/30/13
to pon...@googlegroups.com
没有操作符重载就等着被Java里面混乱邪恶的"=="和“equals”虐吧


2013/4/30 猛禽 <rapt...@gmail.com>

microcai

unread,
Apr 30, 2013, 8:21:51 PM4/30/13
to pon...@googlegroups.com

在 2013年4月30日 星期二 05:05:44,猛禽 写道:

至少在模板参数可以使用函数对象之前,()重载的用处我觉得还是比较有限的。

很多年不用C++,不知道现在已经可以了,大概会比以前有用一些吧。

其实运算符重载用得恰当的确是个神器,但太容易被滥用了…

 

啥, "不知道现在已经可以了" ?????? 莫非大神是在 80 年代用过的 C++ ????????????

唐风

unread,
Apr 30, 2013, 9:55:11 PM4/30/13
to TopLang
重载运算符(包括不限于())能让程序员做出来的东西长得像语言内建操作一样,让人有”改造语言“的快感,这个很上瘾。(特别是对于我,如此地上瘾以至于因为Scala在这一点上更加激进而转头学Scala)。
装理性地说,
1. 重载运算符让程序有机会更加易懂(因为运算符是入门必学,比如上面Matrix的例子),
2. 也让我们创建的类型和语言内置类型能在语法表现上保持一致(满足了一致性和简洁性的审美,心里爽~~),从而使得模板写起来通用性更强。

不过对我来说,还是”改造语言“的快感是主要的。哇哈哈哈哈
(不要讨论误入歧途神马的,谢谢)

当然,()运算符因为有”调用“的语义所以引申出来的层面更广。不过没有lambda时函数对象这个用起来真心累,有了lambda之后也主要是做快速创建临时的小型可调用对象的语法糖(再次说,我大爱语法糖)。用做”闭包“,我特别是指携带着不属于lambda自身的局部变量在函数之间传来传去的那种”函数式“编程风格,在C++中还没成气候吧,另外,我对这种搞法的”可读性“也表示怀疑。

另,歪下楼,C++发展到今天,有这么许多超出C之外特异的语法,我觉得特别缺一个好的”代码阅读器“(像Source Insight对于C那样),有一个好的代码阅读器的话,可以很大程度地降低C++代码阅读的心智负担并提高可维护性。





--

microcai

unread,
May 1, 2013, 12:19:56 AM5/1/13
to pon...@googlegroups.com
> 在 2013年5月1日 星期三 10:55:11,唐风 写道:
>
>
> 重载运算符(包括不限于())能让程序员做出来的东西长得像语言内建操作一样,让人有”改造语言“的快感,
这个很上瘾。(特别是对于我,如此地上瘾以至于因为Scala在这一点上更加激进而转头学Scala)。
> 装理性地说,
> 1. 重载运算符让程序有机会更加易懂(因为运算符是入门必学,比如上面Matrix的例子),
> 2. 也让我们创建的类型和语言内置类型能在语法表现上保持一致(满足了一致性和简洁性的审美,心里爽
~~),从而使得模板写起来通用性更强。
>

没错, C++ 是一个强调语义一致性的语言. 和 java python 这种不入流的垃圾不可同日而语.

>
> 不过对我来说,还是”改造语言“的快感是主要的。哇哈哈哈哈
> (不要讨论误入歧途神马的,谢谢)
>
>
> 当然,()运算符因为有”调用“的语义所以引申出来的层面更广。不过没有lambda时函数对象这个用起来真心
累,有了lambda之后也主要是做快速创建临时的小型可调用对象的语法糖(再次说,我大爱语法糖)。用
做”闭包“,我特别是指携带着不属于lambda自身的局部变量在函数之间传来传去的那种”函数式“编程风格,在
C++中还没成气候吧,另外,我对这种搞法的”可读性“也表示怀疑。
>

lambda 就是函数对象的语法糖. 但是如果是大片的代码, 还是老实写 operator() . lambda 只适合非常短的地
方, 一两行就能解决的那种.

>
> 另,歪下楼,C++发展到今天,有这么许多超出C之外特异的语法,我觉得特别缺一个好的”代码阅读器“(像
Source Insight对于C那样),有一个好的代码阅读器的话,可以很大程度地降低C++代码阅读的心智负担并提
高可维护性。
>
>
>
>
>
>
>
>
> 在 2013年5月1日上午9:21,microcai <micro...@gmail.com[1]>写道:
>
>
> 在 2013年4月30日 星期二 05:05:44,猛禽 写道:
>
>
> 至少在模板参数可以使用函数对象之前,()重载的用处我觉得还是比较有限的。
> 很多年不用C++,不知道现在已经可以了,大概会比以前有用一些吧。
> 其实运算符重载用得恰当的确是个神器,但太容易被滥用了…
>
>
>
> 啥, "不知道现在已经可以了" ?????? 莫非大神是在 80 年代用过的 C++ ????????????
> -- --- 您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。要退订此论坛并停止接收此论

坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com[2]。要查看更多选项,请访问
https://groups.google.com/groups/opt_out。[3]


>
>
>
> -- --- 您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。要退订此论坛并停止接收此论
坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com。要查看更多选项,请访问
_https://groups.google.com/groups/opt_out。_
>
>
>
>
> --------

> [1] mailto:micro...@gmail.com
> [2] mailto:pongba%2Bunsu...@googlegroups.com
> [3] https://groups.google.com/groups/opt_out
>

猛禽

unread,
May 1, 2013, 3:34:28 AM5/1/13
to pon...@googlegroups.com
鄙人作为从C++改到python上的程序员,坚决不同意这种说法…
像这里讨论的什么的闭包、协程、Functor之类,在python里都显而易见,易如反掌,根本不用搞得这么复杂,复杂到没有多年C++功力的人根本玩不转。
像operator ()这种东西,在python里只要一个__call__方法即可实现,更加直观易懂。
lambda本来就是表达式,拿来实现大段代码本来就是错误的用法,python里甚至不允许这么做,只有能写成表达式的语句才能用来写lambda。
lambda不同于java里的匿名函数。

在 2013年5月1日星期三UTC+8下午12时19分56秒,microcai写道:

microcai

unread,
May 1, 2013, 4:05:19 AM5/1/13
to pon...@googlegroups.com
> 在 2013年5月1日 星期三 00:34:28,猛禽 写道:
>
>
> 鄙人作为从C++改到python上的程序员,坚决不同意这种说法… 像这里讨论的什么的闭包、协程、Functor之

类,在python里都显而易见,易如反掌,根本不用搞得这么复杂,复杂到没有多年C++功力的人根本玩不转。
像operator ()这种东西,在python里只要一个__call__方法即可实现,更加直观易懂。 lambda本来就是表达
式,拿来实现大段代码本来就是错误的用法,python里甚至不允许这么做,只有能写成表达式的语句才能用来
写lambda。 lambda不同于java里的匿名函数。
>

python 里充满了这种"做作" 的强制. 以表明设计者是个 "很重视优雅" 的人.

其实说白了 python 是个门外汉设计给门外汉的语言.

>
>

liu yongjian

unread,
May 1, 2013, 5:54:09 AM5/1/13
to pon...@googlegroups.com
不好意思啊。我问个问题,我没订阅此邮件,为什么不断的给我发啊。


shiwei xu

unread,
May 1, 2013, 6:41:22 AM5/1/13
to pongba
反感这种给其他语言打标签的人。
虽然你喜欢c++,但也没必要通过贬低其他语言的创始人来抬高c++。
如果你像我一样,用c++做了10多年的程序,带团队做了多个项目,你就知道c++对程序员的素质要求有多高,你就知道什么语法优雅的一致性都是浮云。



>
>

--

---
您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out





--

tinyfool(郝培强)

unread,
May 1, 2013, 7:09:51 AM5/1/13
to pon...@googlegroups.com
同意,且同意工程上的考虑其实也很重要

发自我的 iPhone4

猛禽

unread,
May 1, 2013, 7:16:26 AM5/1/13
to pon...@googlegroups.com

我已经说了,lambda表达式不等于匿名函数,所以这根本谈不上"做作"的强制。
至于C++为了实现这些而用了那些迂回的办法,又何尝不是为了"语法一致性"不得已而为呢?
另,同意老许意见。

> --
>
> ---
> 您收到此邮件是因为您订阅了 Google 网上论坛“TopLanguage”中的主题。
> 要退订此主题,请访问 https://groups.google.com/d/topic/pongba/gBpPkoXvdeY/unsubscribe?hl=zh-CN
> 要退订此论坛及其所有主题,请发送电子邮件到 pongba+un...@googlegroups.com
> 要查看更多选项,请访问 https://groups.google.com/groups/opt_out
>
>

microcai

unread,
May 1, 2013, 6:59:03 AM5/1/13
to pon...@googlegroups.com
> 在 2013年5月1日 星期三 18:41:22,shiwei xu 写道:
>
>
> 反感这种给其他语言打标签的人。
> 虽然你喜欢c++,但也没必要通过贬低其他语言的创始人来抬高c++。
> 如果你像我一样,用c++做了10多年的程序,带团队做了多个项目,你就知道c++对程序员的素质要求有多
高,你就知道什么语法优雅的一致性都是浮云。
>

事实就是这样, python 靠所谓的 "简单" 吸引大量的开发者. 可是 python 事实上是不够资格作为一门编程语言
的.
python 只能是脚本. 而脚本语言有比 python 优秀百倍的 javascript .

我给出了详细的 python 为啥很烂的解释
https://avlog.avplayer.org/3597082/python%E6%98%AF%E4%B8%AA%E7%83%82%E8%AF%AD%E8%A8%80.html


我可不是那种简单的给打个标签 缺乏根据在那里胡扯 的那种人.

谁要是不同意可以逐条反驳.

Joseph Shen

unread,
May 1, 2013, 8:46:20 AM5/1/13
to pon...@googlegroups.com
插句话啊,
>>>也会使用"单根继承" 这种恶心的策略. (  hei ,我说的是 你 ! MFC 和 Qt .) 通过基类指针来代替 void*<<<
这句不是很理解啊?
就本人有限的经验而言MFC和Qt的单根继承也不是要解决你说的问题啊?!
你举的栗子不是很恰当吧?用不着打击MFC和Qt显示你很NB啊?
改造语言特性的做法,我觉得到了一定程度也是很常见的,无论是C++还是Python,只要你觉得自己能够处理好。


--
 
---
您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 

xiandi xu

unread,
May 1, 2013, 9:09:13 AM5/1/13
to pon...@googlegroups.com

黑猫白猫能抓到老鼠就是好猫。

microcai

unread,
May 1, 2013, 9:11:34 AM5/1/13
to pon...@googlegroups.com
> 在 2013年5月1日 星期三 20:46:20,Joseph Shen 写道:
>
>
> 插句话啊,>>>也会使用"单根继承" 这种恶心的策略. ( hei ,我说的是 你 ! MFC 和 Qt .) 通过基类指针来代替
void*<<<
>
> 这句不是很理解啊?

MFC 有一个公有的基类 CObject , Qt 也有一个公共基类 QObject .


> 就本人有限的经验而言MFC和Qt的单根继承也不是要解决你说的问题啊?!
> 你举的栗子不是很恰当吧?用不着打击MFC和Qt显示你很NB啊?

打击他不是为了显示我很 NB , 只是单纯的觉得就应该打击一下. 你想多了.

> 改造语言特性的做法,我觉得到了一定程度也是很常见的,无论是C++还是Python,只要你觉得自己能够处
理好。
>

junyi sun

unread,
May 1, 2013, 9:16:45 AM5/1/13
to pon...@googlegroups.com
很多人都是python和C++都会吧。


2013/5/1 xiandi xu <xuxi...@gmail.com>

猛禽

unread,
May 1, 2013, 10:14:00 AM5/1/13
to pon...@googlegroups.com
哈哈哈,原来这段就是你说的啊…
那我可以打住了,因为这段前几天就在别的地方看到过,完全就是“缺乏根据在那里胡扯”。


--

---
您收到此邮件是因为您订阅了 Google 网上论坛“TopLanguage”中的主题。
要退订此主题,请访问 https://groups.google.com/d/topic/pongba/gBpPkoXvdeY/unsubscribe?hl=zh-CN
要退订此论坛及其所有主题,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out





--
猛禽
http://raptor.verybs.com
https://8gua.me/blog
http://blog.csdn.net/raptor

Joseph Shen

unread,
May 1, 2013, 10:08:47 AM5/1/13
to pon...@googlegroups.com
我知道是公共基类,但是它们的目的和你说的不一样。

Yongwei Wu

unread,
May 1, 2013, 11:17:54 AM5/1/13
to pon...@googlegroups.com
不都是为了效率嘛。举一个不恰当的例子,前些天在SHLUG上讨论一个算法题,我在网上找到一个使用函数式编程风格的Python解,把它几乎是逐行转成了C++11的代码,运行时间立马缩减到约十分之一。

之所以说不恰当,是因为这个例子里,运行时间和编程时间相比总是可以忽略不计的。世界上应当有很多这样的问题,使用Python在一般情况下是比C++更好的选择。但也有不少问题,特别是放在普通用户机器、设备上运行的代码,性能非常重要,C++会是更好的选择。

2013/5/1 猛禽 <rapt...@gmail.com>
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 

Yongwei Wu

unread,
May 1, 2013, 11:29:29 AM5/1/13
to pon...@googlegroups.com
2013/5/1 microcai <micro...@gmail.com>

其他算了,对于云风的评论不能苟同。我见过云风两次,前一次时他是C++的拥护者,后一次时(大概四年后)他基本放弃了使用C++。我跟他讨论过原因,对他的观点也能够理解。简单来说,就是他后面采用的方法是游戏的上下层完全分离,底层使用C写核心工具,上层游戏逻辑对程序员的要求就低了,用LUA来写。性能和简单性兼顾,但这么做的原因实质上是人的问题。如果所有的代码都由他自己写,他就不一定这样组织代码了吧。

qiaojie

unread,
May 1, 2013, 12:23:58 PM5/1/13
to pon...@googlegroups.com
C++搞闭包是天生残疾,因为没有GC特性,所以闭包的生存周期管理就是个问题,手工delete会让人抓狂,所以要么当值拷贝来拷贝去的浪费性能,要么用引用计数传来传去的,还是浪费性能。


在 2013年4月30日上午9:35,microcai <micro...@gmail.com>写道:

话说 C++ 语言里的一个伟大的决策就是能进行运算符重载.

而这么多运算符重载里, 最最最豪华有用便利神器的,就是 () 运算符重载了.

() 运算符重载,就能将一个对象作为一个函数, 以实现闭包.

闭包是非常有用的功能, C 语言因为不支持闭包, 必须搞个邪恶的 void* 作为回调参数之一. 而不懂得使用闭包
的人, 也会使用"单根继承" 这种恶心的策略. (  hei ,我说的是 你 ! MFC 和 Qt .) 通过基类指针来代替 void*

闭包可不简简单单的用来做 for_each 的参数, 更重要的是用来实现协程.

用闭包实现的协程, 无需一个例程用于上下文切换 (swap_context(3) 和 Win32 里的 Fiber)

所有的状态都保存在了成员变量里.

hi, 砖头出了, 欢迎玉

qiaojie

unread,
May 1, 2013, 12:32:32 PM5/1/13
to pon...@googlegroups.com
另外函数对象显式的实现闭包其实也是很丑陋的做法,其他语言中的闭包都是编译器自动捕获up-value隐式构造闭包,闭包的生存期也通过GC自动管理,无须写额外的代码。而用函数对象实现的闭包则需要自己定义对象,多了很多不必要的代码,虽然C++11已经支持了lambda,可以隐式构造闭包了,但是生存期管理依然是个麻烦的问题。
建议楼主多学习一下其他语言,开阔一下眼界,就会觉得C++的世界其实很苦逼。

唐风

unread,
May 1, 2013, 12:48:13 PM5/1/13
to TopLang
Agree
有体会,用了其它语言回来再用C++,有些地方是”带着脚镣跳舞“了。

不过在保证性能尽可能地极致的情况下尽量提供抽象手段就C++了呀,在嵌入式中资源有限不带虚拟机,Java/C#/Python都不是第一选啊,用C吧连搞个链表都觉得很苦逼啊。感谢C++,如果编译速度能上去我就真不抱怨了,哈哈。

Yongwei Wu

unread,
May 1, 2013, 12:59:50 PM5/1/13
to pon...@googlegroups.com
还没仔细看实现,粗想一下,闭包的数据量实际上主要也就是由捕获的数据量决定。一般情况下并没什么问题。况且,脚本语言有GC性能也没法跟C++比。GC带来的缺点也是很显然的,特别是内存占用。

2013/5/2 qiaojie <qia...@gmail.com>

qiaojie

unread,
May 1, 2013, 1:21:14 PM5/1/13
to pon...@googlegroups.com
不是只有脚本语言才支持闭包的,其他静态类型的语言也有很多支持闭包的(除了比较落伍的java)。如果把C++函数一个个孤立起来看,确实可以做到极致的高性能,但是如果放到整个系统层面,C++的复杂性往往会带来很多意想不到的坑,比如说频繁的创建删除对象,造成内存碎片,还有各种内存泄漏等等。在我的职业生涯中,曾经有过一次用C++写的游戏,在变态的24小时连续压力测试中,因为内存碎片以及一个第三方库中的一个很小的内存泄漏,导致内存无法分配而程序crash,最后换了内存分配器,打了patch才通过测试。
另外,所谓GC造成的内存占用,在我实践中是没有出现过什么大问题的,我写的服务器运行几个月内存占用都很平稳,真的有问题,也很容易通过profiling工具定位。

microcai

unread,
May 1, 2013, 9:15:13 PM5/1/13
to pon...@googlegroups.com
> 在 2013年5月2日 星期四 00:23:58,qiaojie 写道:


> C++搞闭包是天生残疾,因为没有GC特性,所以闭包的生存周期管理就是个问题,手工delete会让人抓狂,所
以要么当值拷贝来拷贝去的浪费性能,要么用引用计数传来传去的,还是浪费性能。
>

c++11 有 Move 语义

Yongwei Wu

unread,
May 1, 2013, 10:21:04 PM5/1/13
to pon...@googlegroups.com
GC的问题在服务器上我觉得不明显。在客户端、特别是移动设备上较明显。iPhone完全是不用GC的,设备对内存的需求明显比Android的低。

顺便问一句,你用什么语言?

2013/5/2 qiaojie <qia...@gmail.com>

不是只有脚本语言才支持闭包的,其他静态类型的语言也有很多支持闭包的(除了比较落伍的java)。如果把C++函数一个个孤立起来看,确实可以做到极致的高性能,但是如果放到整个系统层面,C++的复杂性往往会带来很多意想不到的坑,比如说频繁的创建删除对象,造成内存碎片,还有各种内存泄漏等等。在我的职业生涯中,曾经有过一次用C++写的游戏,在变态的24小时连续压力测试中,因为内存碎片以及一个第三方库中的一个很小的内存泄漏,导致内存无法分配而程序crash,最后换了内存分配器,打了patch才通过测试。
另外,所谓GC造成的内存占用,在我实践中是没有出现过什么大问题的,我写的服务器运行几个月内存占用都很平稳,真的有问题,也很容易通过profiling工具定位。


在 2013年5月2日上午12:59,Yongwei Wu <wuyo...@gmail.com>写道:

还没仔细看实现,粗想一下,闭包的数据量实际上主要也就是由捕获的数据量决定。一般情况下并没什么问题。况且,脚本语言有GC性能也没法跟C++比。GC带来的缺点也是很显然的,特别是内存占用。

2013/5/2 qiaojie <qia...@gmail.com>
C++搞闭包是天生残疾,因为没有GC特性,所以闭包的生存周期管理就是个问题,手工delete会让人抓狂,所以要么当值拷贝来拷贝去的浪费性能,要么用引用计数传来传去的,还是浪费性能。

 

吴和顺

unread,
May 1, 2013, 10:37:14 PM5/1/13
to pon...@googlegroups.com
在c++中,GC的问题可以用smart pointer来解决


--

吴和顺

unread,
May 1, 2013, 10:40:42 PM5/1/13
to pon...@googlegroups.com
这个内存碎片的问题,在c++中,很容易用内存池来解决,boost库就有提供的

Ryan Feng

unread,
May 1, 2013, 11:46:18 PM5/1/13
to pon...@googlegroups.com
smart pointers只能是辅助,况且很多内存问题也不是有了GC就能完全解决了的,比如内存泄漏。


2013/5/1 吴和顺 <hesh...@gmail.com>

qiaojie

unread,
May 2, 2013, 1:11:35 AM5/2/13
to pon...@googlegroups.com
C#


在 2013年5月2日上午10:21,Yongwei Wu <wuyo...@gmail.com>写道:
--

qiaojie

unread,
May 2, 2013, 1:18:06 AM5/2/13
to pon...@googlegroups.com
用内存池就会预分配内存,就会浪费一部分内存空间,有些内存池在释放对象的时候不会把内存归还给系统

qiaojie

unread,
May 2, 2013, 1:37:54 AM5/2/13
to pon...@googlegroups.com
在 2013年5月2日上午10:21,Yongwei Wu <wuyo...@gmail.com>写道:
GC的问题在服务器上我觉得不明显。在客户端、特别是移动设备上较明显。iPhone完全是不用GC的,设备对内存的需求明显比Android的低。


拿ios和android来对比GC的影响这很不科学,大多数情况下是因为ios程序审核比较严格,而android基本上没什么审核,有很多滥竽充数的应用滥用了内存。另外也跟API的开放程度有关系,比如ios是不允许有第三方的后台进程的。



tinyfool(郝培强)

unread,
May 2, 2013, 1:48:41 AM5/2/13
to pon...@googlegroups.com
iOS不允许任意app后台而已,后台还是有大量第三方App的

发自我的 iPhone4

Zhenghui Zhou

unread,
May 2, 2013, 2:16:03 AM5/2/13
to pon...@googlegroups.com
继续跑题,也谈GC。

不否认gc在解决内存释放问题/错误上有很大帮助,可能有些场合也能带来很大便利。 个人主观上有点排斥GC,可能是性格过于追求完美在作祟。

无论从内存使用还是性能上说,GC都不应会比设计得当的非GC方案强。更何况,如果有内存使用上错误也往往意味着代码里还潜有其他错误的可能,至少思维逻辑上存有遗漏。所以内存泄露也有利于把这些错漏一一找出来,而我们所要做的重心也自然转移到更好的规划设计上,以使得查错过程自然完备。

另外一个不使用GC的重要理由是定制的优化内存使用方案成为可能。实际中任何一个普适的内存分配方案和GC都存在不可逆转的劣化趋势,所以有了内存池等措施来祢补。无论是java这样平台如何的优化,我想它们在内存消耗上都是为人所诟病的主要方面之一。

当然如果写一些并不重要的代码,或者不在意资源和偶发性的错误,这些都是次要的。

猛禽

unread,
May 2, 2013, 2:33:10 AM5/2/13
to pon...@googlegroups.com
GC的问题我曾经与云风有过争论,我原来的观点跟你差不多,但最终他说服了我。我接受GC的理由主要有几个:
首先一点,内存已经足够便宜,为了省一点点内存而去做优化,所花的代价远高于买内存的成本,除非的确是对内存使用有苛刻要求的应用,否则GC之类的已经足够好。
其次,自定义内存管理存在的BUG风险远大于现成的GC实现。
第三,除非对每个特定应用定制内存管理方案,否则未必能比技术成熟的GC好到哪里去。

在 2013年5月2日星期四UTC+8下午2时16分03秒,zhouzh...@gmail.com写道:

Zhenghui Zhou

unread,
May 2, 2013, 2:53:49 AM5/2/13
to pon...@googlegroups.com
内存便宜实在难以成为一个理由,就好像人们不会再抱怨他们电脑慢了一样。

回到开发的角度,我以为内存分配是十分低层的东西,也就是从高层语义讲是可以被附加的层次所隐藏掉的(当然实际不一定都这么做),所以在开发大的东西应该少有机会跟内存打交道,除非它就是应用所关注的逻辑的组成(内存池,GC等)。

所以在看到浏览器在不停偷嗜内存和CPU时,我会暴怒的骂开发它的蠢货们。尽管我也知道做好并不容易,但我想开发操作系统的那帮人或许会有不同的想法。

qiaojie

unread,
May 2, 2013, 2:55:10 AM5/2/13
to pon...@googlegroups.com
这事其实没什么好争论的,基本上手工内存管理的语言就剩那么几个了,obj-c也开始支持GC了,90年代后发展出来的新的主流编程语言基本上全都是基于GC的,这说明业界一致认为GC才是主流。C++0x标准本来也在讨论是否要加入GC,只是C++自身的设计缺陷导致很难完美的加入GC支持,最终作罢。
另外说一句,我不是C++黑,我平时也写C++代码,但是C++用的越多才越能体会C++的痛点在哪里,当然前提是你要有足够的眼界,对其他编程语言有足够的了解。

Yongwei Wu

unread,
May 2, 2013, 2:57:52 AM5/2/13
to pon...@googlegroups.com
移动应用的兴起,恰恰让人们觉得省一点点内存都是值得的。可以说,这是C++最近似乎有点重新变热的原因。

2013/5/2 猛禽 <rapt...@gmail.com>

GC的问题我曾经与云风有过争论,我原来的观点跟你差不多,但最终他说服了我。我接受GC的理由主要有几个:
首先一点,内存已经足够便宜,为了省一点点内存而去做优化,所花的代价远高于买内存的成本,除非的确是对内存使用有苛刻要求的应用,否则GC之类的已经足够好。
其次,自定义内存管理存在的BUG风险远大于现成的GC实现。
第三,除非对每个特定应用定制内存管理方案,否则未必能比技术成熟的GC好到哪里去。

Yongwei Wu

unread,
May 2, 2013, 3:04:10 AM5/2/13
to pon...@googlegroups.com
GC在Objective-C里已经被deprecate了。现在Objective-C里推荐使用的是ARC技术。详见:


所以,不存在什么“业界一致认为GC才是主流”。

2013/5/2 qiaojie <qia...@gmail.com>

猛禽

unread,
May 2, 2013, 3:04:45 AM5/2/13
to pon...@googlegroups.com
但事实就是如此,你也说了现在的软件根本不介意越来越多地占用内存——因为对这些软件开发者来说,有太多事情比省内存要重要得多。我猜测这也与历史经验有关……当年Lotus 1-2-3为了在新版本里节省内存,又增加功能,最后导致发布日期不断推迟,最终产品还BUG巨多。相比之下,微软的Excel以多占内存,但随着硬件技术的进步而战领市场。
节约内存的成本太高了……
至于说C++增加GC,也并不是不可能,比如Managed C++……据Milo老师实测,比起原生的C++,性能下降非常有限。
还有像闭包这种东西,十几年前Borland就在C++Builder里搞了一个私有的实现。
至于移动应用开发里用C++,倒也不完全是为了内存,更多的是为了性能——至少在android平台下,java虚拟机的性能终归还是没法跟C++的原生代码相比。

在 2013年5月2日星期四UTC+8下午2时55分10秒,qiaojie写道:

qiaojie

unread,
May 2, 2013, 3:04:57 AM5/2/13
to pon...@googlegroups.com
C++在移动应用上变热,主要是因为移植性的关系。原本开发商在PC上用C++做的应用要移植到手机上,ios和android各有不同的开发语言,移植成本较高,如果继续沿用C++的话,就可以节省很多成本了。
这年头关注内存占用的基本没有,手机上现在大多也有1G内存了,一般来说最耗内存的是图像资源,这个不管用不用GC都是一样的。


--
 
---
您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。

猛禽

unread,
May 2, 2013, 3:06:37 AM5/2/13
to pon...@googlegroups.com
是的,移植也是很重要的一个方面,比如那些视频播放软件,大多是从PC平台的开源代码移植过去的,没人会去用JAVA重写一遍。


--
 
---
您收到此邮件是因为您订阅了 Google 网上论坛“TopLanguage”中的主题。
要退订此主题,请访问 https://groups.google.com/d/topic/pongba/gBpPkoXvdeY/unsubscribe?hl=zh-CN。
要退订此论坛及其所有主题,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 



--
猛禽
http://raptor.verybs.com
https://8gua.me/blog
http://blog.csdn.net/raptor

Yongwei Wu

unread,
May 2, 2013, 3:09:15 AM5/2/13
to pon...@googlegroups.com
性能和内存占用绝对是相关的。纯粹的计算性能,Java并不差。额外的内存占用会引起更多的缓存不命中,额外的内存管理器也绝不是零开销的。

2013/5/2 猛禽 <rapt...@gmail.com>

但事实就是如此,你也说了现在的软件根本不介意越来越多地占用内存——因为对这些软件开发者来说,有太多事情比省内存要重要得多。我猜测这也与历史经验有关……当年Lotus 1-2-3为了在新版本里节省内存,又增加功能,最后导致发布日期不断推迟,最终产品还BUG巨多。相比之下,微软的Excel以多占内存,但随着硬件技术的进步而战领市场。
节约内存的成本太高了……
至于说C++增加GC,也并不是不可能,比如Managed C++……据Milo老师实测,比起原生的C++,性能下降非常有限。
还有像闭包这种东西,十几年前Borland就在C++Builder里搞了一个私有的实现。
至于移动应用开发里用C++,倒也不完全是为了内存,更多的是为了性能——至少在android平台下,java虚拟机的性能终归还是没法跟C++的原生代码相比。

qiaojie

unread,
May 2, 2013, 3:10:19 AM5/2/13
to pon...@googlegroups.com
Managed C++或者叫C++/CLI,那个就不是C++了,是跑在 .net虚拟机上的C++,不能编译成native code单独运行,基本上没人用。c++0x也不可能采用这样的GC方案。

lor fal

unread,
May 2, 2013, 9:21:32 PM5/2/13
to pon...@googlegroups.com
C++/CLI也并不是完全没用,java还有个JNI可以用来跟native code交互。C++或许用不着语言层面支持GC,有没有可能写个可配置,可扩展的GC库。


2013/5/2 qiaojie <qia...@gmail.com>



--
Best regards,
LORFAL

Shuo Chen

unread,
May 5, 2013, 6:09:49 PM5/5/13
to pon...@googlegroups.com
四年前就讨论过了,论坛上没啥新鲜事儿。

https://groups.google.com/d/msg/pongba/EvTsUTzV-H0/m36F5wm3hAQJ


On Monday, April 29, 2013 8:27:13 PM UTC-7, Tinyfool wrote:
这属于唯恐天下不乱么?

我对C++不是很懂,欢迎大家拍砖


2013/4/30 microcai <micro...@gmail.com>


话说 C++ 语言里的一个伟大的决策就是能进行运算符重载.

而这么多运算符重载里, 最最最豪华有用便利神器的,就是 () 运算符重载了.

() 运算符重载,就能将一个对象作为一个函数, 以实现闭包.

闭包是非常有用的功能, C 语言因为不支持闭包, 必须搞个邪恶的 void* 作为回调参数之一. 而不懂得使用闭包
的人, 也会使用"单根继承" 这种恶心的策略. (  hei ,我说的是 你 ! MFC 和 Qt .) 通过基类指针来代替 void*

闭包可不简简单单的用来做 for_each 的参数, 更重要的是用来实现协程.

用闭包实现的协程, 无需一个例程用于上下文切换 (swap_context(3) 和 Win32 里的 Fiber)

所有的状态都保存在了成员变量里.

hi, 砖头出了, 欢迎玉




--

---
您收到此邮件是因为您订阅了 Google 网上论坛的“TopLanguage”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 pongba+un...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out


@@

unread,
May 5, 2013, 11:27:03 PM5/5/13
to pon...@googlegroups.com
你这这文章写个 javascript版的更简单。 


2013/5/1 microcai <micro...@gmail.com>
> 在 2013年5月1日 星期三 18:41:22,shiwei xu 写道:
>
>
> 反感这种给其他语言打标签的人。
> 虽然你喜欢c++,但也没必要通过贬低其他语言的创始人来抬高c++。
> 如果你像我一样,用c++做了10多年的程序,带团队做了多个项目,你就知道c++对程序员的素质要求有多
高,你就知道什么语法优雅的一致性都是浮云。
>

事实就是这样, python 靠所谓的 "简单" 吸引大量的开发者. 可是 python 事实上是不够资格作为一门编程语言
的.
python 只能是脚本. 而脚本语言有比 python 优秀百倍的 javascript .

我给出了详细的 python 为啥很烂的解释
https://avlog.avplayer.org/3597082/python%E6%98%AF%E4%B8%AA%E7%83%82%E8%AF%AD%E8%A8%80.html


我可不是那种简单的给打个标签 缺乏根据在那里胡扯 的那种人.

谁要是不同意可以逐条反驳.

AthrunArthur

unread,
May 6, 2013, 2:28:36 AM5/6/13
to pon...@googlegroups.com
嗯,关于C++ 的代码阅读器, 非常同意,其实基于clang的话,实现起来应该比较简单,但是目前好像还是只有在vim上集成了,期待更好用的~

On Wednesday, May 1, 2013 9:55:11 AM UTC+8, 唐风 wrote:
> 重载运算符(包括不限于())能让程序员做出来的东西长得像语言内建操作一样,让人有”改造语言“的快感,这个很上瘾。(特别是对于我,如此地上瘾以至于因为Scala在这一点上更加激进而转头学Scala)。
> 装理性地说,
> 1. 重载运算符让程序有机会更加易懂(因为运算符是入门必学,比如上面Matrix的例子),
> 2. 也让我们创建的类型和语言内置类型能在语法表现上保持一致(满足了一致性和简洁性的审美,心里爽~~),从而使得模板写起来通用性更强。
>
>
>
> 不过对我来说,还是”改造语言“的快感是主要的。哇哈哈哈哈
> (不要讨论误入歧途神马的,谢谢)
>
>
> 当然,()运算符因为有”调用“的语义所以引申出来的层面更广。不过没有lambda时函数对象这个用起来真心累,有了lambda之后也主要是做快速创建临时的小型可调用对象的语法糖(再次说,我大爱语法糖)。用做”闭包“,我特别是指携带着不属于lambda自身的局部变量在函数之间传来传去的那种”函数式“编程风格,在C++中还没成气候吧,另外,我对这种搞法的”可读性“也表示怀疑。
>
>
>
> 另,歪下楼,C++发展到今天,有这么许多超出C之外特异的语法,我觉得特别缺一个好的”代码阅读器“(像Source Insight对于C那样),有一个好的代码阅读器的话,可以很大程度地降低C++代码阅读的心智负担并提高可维护性。
>
>
>
>
>
>
>
>
>
>
> 在 2013年5月1日上午9:21,microcai <micro...@gmail.com>写道:
>
>
>
>
>
> 在 2013年4月30日 星期二 05:05:44,猛禽 写道:
>
>
>
> 至少在模板参数可以使用函数对象之前,()重载的用处我觉得还是比较有限的。
>
> 很多年不用C++,不知道现在已经可以了,大概会比以前有用一些吧。
>
> 其实运算符重载用得恰当的确是个神器,但太容易被滥用了…
>
>
>  
>
> 啥, "不知道现在已经可以了" ?????? 莫非大神是在 80 年代用过的 C++ ????????????

幻の上帝

unread,
May 10, 2013, 9:16:58 AM5/10/13
to pon...@googlegroups.com
似乎看漏了更有趣的东西。
说到语法/语义一致性……只能呵呵了。不说“高阶”抽象的长期确实,就看不到现在重复的东西么?
https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/D1QujphDhhQ
Py没兴趣我是洗不了,不过反正C++也洗不干净。

Reply all
Reply to author
Forward
0 new messages