C++小思
Bjarne那稀疏的棕褐色头发, 有点红的眼睛, 这个可爱的好老头, 感觉他更应该是一个哲学家, 因为他用编程的语言C++
揭示了我们这个纷繁复杂世界的本质: 对象. 对的, 世界是由对象组成的, 并由对象之间发生的关系和通信-互动而推动发展, 存在的
世界应该不是过程的, 因为世界不是机器, 可以按照"程序"而机械的运行. 生命是最神奇, 最"不听话"的, 你只能用消息,daemon,守护的方式
来组织程序, 一旦你程序中的所有对象之间, 都正常运行, 正常"交往", 类似实际世界生活中的那样运作了, 你的程序就没问题了, 也就是一个"代码世界"了
-----------------------------------------------
这是从网上摘录的一段话(朝闻道的博客园:http://www.cnblogs.com/findumars/p/4209430.html)
语言争论真的是很多很多,但可以归根结底,是由于人之3~5年所学,不希望别人轻易否定过时或者不行,这不就等于在否定这个人么?
其实,C++能活到现在还前三(至少也是有科学依据的,对吧),一是历史遗留,二是确实有过人之处,正所谓,可恨之人必有可敬之处。
现
在C++的问题,不在于其庞大,因为你尽可以选择自己喜欢的部分,而不需要求全。C++的问题还在于教学上,现存的C++er几乎都是从C学过来的吧,这
样说来,使用C++的方式还是C的方式,C++支持多范式,从前面的讨论就可以看出来,class+template,是的!这才是基于对象而非面向对象
的方式之一。
C++语法是比其他语言多,这也正是他的优势之一,C++可以让我们可以玩,其他语言能玩吗?虽然这句话很偏激,老板也不会喜欢!
语言是配料,不是工具!配料决定了设计方式,所以,语言会决定设计!从而影响更多后续。这也就解释了为什么很多人觉得C++的开发效率和可维护性很差--那是因为你的思维方式不同啊!好
吧,C++并不适合OO,这是OO的局限和C++的局限共同造成的,C++发展到今天,并不是庞大了,而是越来越合理,不过C++走在一条很荆棘的路上,
既要能实现合理的抽象,满足变化,也还要高效的实现效率(设计效率、编译效率、运行效率),这,真惨!不过,生命在于折腾,不是吗?
这段话,
个人深以为是: c++太庞大了, 又没有叫你什么特性都用, 你用你需要的喜欢的部分就得了; 只有当你需要类, oo, 设计类对象层次模式的时候才用c++, 你写函数式组成程序 就用c得了,不要把c++当成c来使用; 我觉得熟练掌握c++的还是有两把刷子吧, 至少那些多态, 指针拷贝避免内存泄漏, 类层次设计, 模板的使用, 真正掌握这些东西的原 理和使用背景/场景的,还是需要点脑力和苦功的吧,( 降龙十八掌跟什么凌波微步比起来, 是啥大粗黑, 是笨重了些, 但打架还是蛮实用的, 武术套路的花架子好看热闹却打 不趴小混混, 救不了小妹救不了孩子的), 你现在说c++不用了,叫人家自废武功,叫人家情何以堪; c++背负的东西太多,既要抽象又要效率,不满意还要打击稀落人家,太刻 薄了吧,对其他语言那么宽容,为什么就不对c++宽容一点呢; 不要说c++程序员懒,人家也要生活/照顾家人老人孩子, 学个c++已经耗费很多精力和时间了, 凭什么要让 c++去学java,ruby,python, 而不劝java,ruby,python去学习c++, 人家用c++也能轻松加愉快的做事获得点生活费养家糊口不就结了.
==最重要的是, 在天朝, 你懂c++,java, ruby有个毛线用啊, 人家老板不懂什么c正正,c鸡鸡, 人家靠养鸡养猪挣了钱, 转行开软件公司, 还不是整天挣钱挣得笑嘻嘻的, 你
还不是整天得跟在人家后面屁颠屁颠的
所以,如果你想做老大,想要你的小弟死心塌地的跟随你, 就永远不要不负责任的说, "不要用c++...", 这样会把小弟弟给吓到的, 而是说"用c++也可以,但是要注意
这个... , 注意这个..."
---------------------------------------------
软件设计同样。比如说,消息循环在派发消息时,只需知道所有UI对象都是个window,都可以响应窗口消息就足够了;它没必要知道每个UI对象究竟是什么——该对象自己知道收到消息该怎么做。
合理划分功能层级、适时砍掉不必要的繁杂信息,一层层向上提供简洁却又完备的信息/接口,高层模块才不会被累死—KISS是最难也是最优的软件设计方法,没有之一。
今后设计类层次模型时, 就要注意c++的封装和多态归以化 的类关系, 要有清晰/明确/严格的类分层模型:
类似osi的七层模型 (参考关系数据库的表-类的设计, 参考 人事关系层次图的设计)
即使你用了面向对象语言,满篇都是class,并不等于就有了归一化的设计。甚至,因为被这些花哨的东西迷惑,反而更加不知道什么才是设计(或者根本就没有设计), 首先要有这种归一化设计的思想和意识...
除非你真正做出了漂亮的设计,然后用面向对象的语法把这个设计声明出来——仅仅声明真正有设计、真正需要人们注意的地方,而不是到处瞎叫唤——否则不可能得到任何好处。(是否: 仔细推敲/思考, 从 你要设计的软件所代表的 现实的实际中/实际的业务中, 去抽象? 你会马上就 感到类之间的关系 好复杂 好交错... )
接口继承没有任何好处。它只是声明某些对象在某些场景下,可以用归一化的方式处理而已。
换句话说,如果不存在“需要不加区分的处理类似的一系列对象”的场合,那么继承不过是在装X罢了。
封装可应付需求变更、归一化可简化(归一化是针对类的使用者的而言的)设计:以上,就是面向对象最最基本的好处。
——其它一切,都不过是在这两个基础上的衍生而已。
换言之,如果得不到这两个基本好处,那么也就没有任何衍生好处.
想要做出KISS的方案,就必须对面对的问题有透彻的了解,有足够的经验和能力,并经过深思熟虑,这才能做出简洁的抽象:至于最终的抽象是面向对象的、
-----------------------------------------
在dos时代, 你可以调用函数库直接操作io, 你就是世界的主人, 是由你自己去跟外界硬件打交道? 调用中断?
在windows/linux, 操作系统接替了你的权力, 跟io(键盘, 鼠标, 显卡屏幕, 硬盘, U盘, 声卡, 视频卡等)打交道, 它搭建了一个平台/框架, 你只能在它搭建的这个平台内(平台之上)活动, 你不能越过(绕过)os去自己用代码操作io? 黑客可以? 或者说, os对你将底层硬件, 如鼠标键盘硬盘的操作给屏蔽了: 你的app要响应鼠标操作/键盘/读写硬盘等, 得要
通过os来完成, 你把你的请求发给os,然后os跟io交互,然后os把交互结果(通过消息?)发给你的app. 这就有点类似proxy代理一样,os代理你去跟io处理
当你的app要去跟硬盘交互,执行读/写硬盘的时候, 是通过os实现的, 这个叫做"系统调用"
当你的app(有ui界面的)要处理鼠标单击/双击, 键盘等事件时,也是由os来实现的,因为你的app根本没有权力(只是一个在框架里的小喽罗,还没有机会去接触上流社会)
去直接侦测鼠标键盘消息, 是由os去捕获鼠标和键盘事件,生成事件消息, 然后把这些消息分发到相应的app, 当你的app ui线程接收到os发送来的消息时, 才进行相应的处理.
os如何把鼠标/键盘事件消息发送给相应的app呢? 我想, 这个应该不难: os根据当前进程, 维护着一个进程表, 记录着当前正在运行的进程, 包括后台服务, 的meta元信息, 如进程的名称, 运行时间, cpu占用率, 当前是哪个程序激活, "在屏幕上的相对位置"等. 当在屏幕上的某个位置单击/双击鼠标等操作时,os根据前面的meta信息, 判断当前点属于哪个app所在的屏幕区域, 从而判断谁将获得这个鼠标事件的消息, 然后就将这个鼠标消息 发送到 这个app的ui线程中, 然后app处理这个消息事件
类库和函数库, 是你去调用它们, 主动权在你这里, 你是程序的幕后主使者, 你是程序运行的管家, 你是"老板", 你要"操心"程序的运行;
框架: 代码已经运行起来了, 你不用去管代码的运行了, 程序已经自举了, 你只要把处理业务的代码作为"回调"函数注册到框架即可, 你是"打工者", 你不操心程序的运行
即是: "老板" -- "打工者" 之间的区别
http://bbs.pinggu.org/thread-3610592-1-1.html
-------------------------------------
自增符号++ -- 只要是放在后面的, 不管它加不加括号, 都是先执行当前语句, 完了再自增1, 也就是说执行当前语句
的时候,指针p的值仍然是先前的初始值, 不是后来增加后的值: c=*p++ , c=(*p)++ , c= *(p++)的执行结果是一样的
-----------------------------------
?? 世界上的计算机, 主要是根据cpu(非主板)来区分架构, 低端的x86架构由intel, amd的cisc指令集(主要是满足多样性:文本/图形/视频/声音的处理),主要用于pc机市场:
包括:如今的主流os平台: windows, linux, mac os x都是用的x86的"架构". 高端的如sun, ibm, compaq的(服务器和嵌入式的sparc, arm, mips等架构)主要用于服务器和工业机的单一性和高性能的RISC指令集
#
# 架构/平台/语言/编译器?
1 架构是针对硬件而言的, 如x86, arm, mips, sparc架构
2 平台是指操作系统, 在指针对某个架构, 如何设计系统, 实现os的自举. 任何一个"硬件"架构, 都需要一个操作系统(主要作用: 是用来管理外部设备的), 包括手机/平板 /嵌入式的arm都应该有一个os, 如:vxworks,android,ios, wince, symbian, Tizen,等等. 同一个硬件架构,可以有多个不同的平台,如x86架构的windows,linux,mac osx
3 语言, 原生态的语言如c/c++, 它只是一种符号, 一堆字符而已, 与os 和 架构无关? 但是毕竟用c/c++编写的程序是要在 "实际的架构和平台上运行的",
所以语言最直接相关的是"编译器": -- 只要有编译器(针对某个架构下某个os平台的该语言的编译器, c/c++可以用在任何架构和平台下)!
一方面, 就像"轮子"和"交通工具"一样, 只要有合适的编译器,c/c++就可以用在任何地方: c/c++是轮子wheel, 架构和平台是vehicle: 轮子通过"摩托车编译 器"可以用在摩托车上,通过"汽车轮子编译器"就可以用在汽车上,通过"飞机轮子编译器"就可以用在飞机上.
另一方面, 虽然编译器都是将 c/c++代码翻译成二进制代码, 但是最后翻译成的 在不同"架构和平台上运行的"二进制代码肯定是不一样的: c/c++
跨平台语言, 但与平台相关, 因为现在是由操作系统做"框架"了, 不管是linux还是windows下的程序, 都是要在os的管理下执行的, 所以可执行的
二进制代码, 肯定得让os平台能够理解吧.
4 那自然,架构和平台不同,编译器也就不同,架构不同,指令集就不同,所以将c/c++代码翻译成二进制的编译器也就不同:
有人说gcc也可以在windows下运行, 编译c++程序,但是:
-gcc本身是一个程序, 因此其格式(调用的os的接口api)也要被os所识别吧, 所以linux下的gcc编译器肯定与windows下的编译器是不同的
-虽然它们的名字是一样的, 都是叫gcc, 其实那是gcc的移植版, 是对原来的gcc做了重新修改的, 所以那不是原生态的gcc, 而叫windows版的gcc!
-再说了,编译elf/pe格式的可执行程序, 完全用c++的库, 一点都不是使用os平台的api, 接口, 库那也几乎是不可能的
# 架构/跨平台是怎么回事?? 虽然windows/linux/mac os x等是运行在x86指令集上的, 但是它们的os自举的过程:采用的设计方式, 自举过程, 系统函数的设计和
代码实现肯定是不同的. 所以, 如果是在windows平台上开发的软件: 其中只要调用了windows系统函数的(或纯windows的东西,如mfc), 肯定就不能在linux平台上运 行,因为通常linux上没有(一定是没有的)windows上那个调用的系统函数等等
#
# project: 两种读音都有: pr2'd3ekt, 'pra(:)d3ekt perfect: 重音在最前面,e发i音: 'p2:fikt consortium: 最后的发[sh]2m
vehicle 'vi2k2l: no entry for vehicle, the main street be crowded with vehicle every morning
# gcc可以编译链接c的库, 但不能链接c++的库, 所以: 用g++ -o obj main.cpp: g++先是调用gcc来编译, 然后g++负责链接c++的库(g++是专门用来编译链接
c++的) elf:executable and linkable format:可执行链接格式
-------------------------------------------