Friday, February 02, 2007

[转载] zz一个北大学子毕业后的感悟(转载)

还有这个


发信人: anxi (司马昭之心,路人皆知), 板面: Optical

标 题: [转载] zz一个北大学子毕业后的感悟(转载)
发信站: 飘渺水云间 (Tue Jan 30 09:39:55 2007), 转信

【 原文由 vicwzh 发表于 Work 讨论区 】
1,我刚工作的时候,在一家小公司,很小很小的。和我一起进去的另外2个都是普通一点的
学校的。我

们刚去的时候,基本上有了电话都是我站起来跑过去接,其它人根本就不动身。以至于到了
后来,电话

一响,如果我不起身,大家就会一直等着,一直等到我终于忍不了了起身去接。每天下班以
后,我要检

查办公室的垃圾袋,看看是不是需要把垃圾袋提走。而其他人,比如老员工和另外的实习生
,他们根本

不会去提垃圾袋。我是北大人。我不狂。

2,工作形势非常严峻。尤其是对于刚毕业的学生。如果是大公司,它们可能有能力支付生
手的培训时间

和金钱,也有能力承受生手因不熟悉业务而给公司带来的损失,但是对于绝大部分小公司,
它们根本就

不愿意或者说无法承受这些。所以在一个大专毕业的熟手和一个北大毕业的生手中间,他们
宁可选择前

者。

3,中关村乃至海淀乃至北京,是一个廉价高等教育人才市场。这个大环境决定了我们在用
人单位眼里,

都是金属,而不是金子。在这里,大学生就是廉价劳动力,商人看刚毕业的大学生的感觉,
和建筑工地

上包工头看民工的眼光没有任何区别。尤其在以赚钱为唯一目的的大部分小公司。所以,刚
毕业的同学

最需要做的,就是赶紧让自己成为一个熟工。

4,在学校的时候,多交几个真心的朋友。因为工作以后,你可能就永远丧失了交朋友的权
力和勇气。特

别是同事,你可能一直到离开某个单位的时候,你都恋恋不舍,觉得这个单位的同事很不错
。但是没准

在后来的某一天,你突然因为偶然的机会发现,每天对你温柔微笑的同事曾经在你背后捅了
一刀或n刀,

而这些刀的直接后果就是你滚蛋。

5,在学校的时候,好好享受自尊的感觉。有人说,他读大学的时候,以为他毕业后要变成
一条狗只需要

3年的时间,但是工作后,他发现对自己真是太不自信了,其实要变成一条狗根本不用3年,
半年就足够

了。这话是我大4时看见的,过了2年后,我发现这条伟大真理完全可以和牛顿定律媲美。我
们在北大里

,享受的是中国最大的自由和民主,这是个可怕的甜蜜。因为当你第一次受到指着鼻子的责
骂时你一下

子无法接受。

6,你在北大的时候,可能会觉得某人很俗。离开北大的时候,你可能会立志你绝对不要俗
。但是过了几

年后,你会发现只有那些完成了由不俗到俗的成功转变的同学才能衣着不俗地参加聚会,而
那些尚未完

成转变的同学则可能潦倒落魄地出现在你面前。所以,当你在学校的时候,千万不要讥笑(
哪怕是在心

里)身边那些俗又俗的同学,因为他们很可能就是将来同学聚会上的主角,也是你mm对你进
行再教育的

榜样。

7,当你在北大的时候,千万不要看不起那些在西门外那排小平房租房准备以考研方式杀进
北大的年轻人

,他们中的某些人在你看来可能很功利、没有道德观、为了目的不达手段。但是你工作后你
会发现这3点

恰恰是北大没有教给我们的生存技能。如果我们能够掌握这3点,再加上我们的学历背景,
北大人一定会

战无不克。事实上,我们中的大部分人在离开学校后都会往这个方向努力,所以,他们其实
是很值得尊

敬的,因为他们比我们成熟得要早。他们可能在更年轻得时候就受过挫折,所以他们懂得从
此以后拼命

。而我们一直是幸福宝宝,等到毕业的时候才开始接受人生中第一次真正意义上的挫折,所
以我们拼命

得比他们要晚了很多。

8,在我们所受到的教育里,师长一直告诉我们要诚实、对人真诚。还有,中国的老话叫“
买卖不成仁义

在”。这在企业竞争已经到人性化程度的西方世界可能还是真理,但是在现在的中国商场上
那是……胡

说。举个例子吧,我的诚实让公司失去了一个客户,让我个人赢得了一个朋友;当这个朋友
因我的诚实

而给我带来一个大买卖时,我已经被公司老板因那次业务失败而炒了鱿鱼;所以最后我把这
宗大买卖带

到了新服务的公司。 这件事的结果最后是好的;但是这只是一个幸运的偶然。我想大部分
人不会这么幸

运。工作以后,如果你每天统计一下,你会惊讶于自己现在从早晨走进办公室的那一刻起就
开始说假话

。这假话对同事说、对老板说、对客户说、一直说到家里,如果你的女友or男友还没有工作
,而是留在

学校上研上博(就像我的情况),你会让他们大为震惊,他们很可能悲痛欲绝地对你说“你
怎么能这么

说?”然后,你可能更加愤慨地对她or他说:“这只是交际的手段/业务的需要/如果你能给
我提供一个

饭碗我肯定不这么说……”最后的最后,你们很可能对彼此失望,比如,对方觉得你变了;
你觉得对方

too naive,too simple,不理解你。

9,北大太自由了,这是身为北大人的幸运,也是不幸。在北大了你可能学会了直言不讳,
而这可能正是

你的老板最忌讳的。中国人都是有劣根性的;中国的富人和西方的富人区别很大,中国的老
板和西方的

老板也很不同。我们看过很多例子,里面讲到某人因为直言而被认为是被炒鱿鱼,最后却升
职了:这种

故事在现实世界中简直就像是……相信灰姑娘当上皇后一样又美丽又白痴。在北大人眼里,
人生来平等

,即使你是老板;北大的人不少是完美主义者,他们看见陈规陋习会直接指出来;这下完蛋
了,因为当

老板发现你在某些方面比他还高明的时候,他会郁闷to death.即使最终他终于采用了你的
建议,你也离

滚蛋不远了。我相信,这也是很多外界评论北大人狂的原因之一。对此我的理解是,呸,有
种的你就说

我们狂,也别用我们的建议,别吃了我的葡萄长了肉还要说葡萄是酸的!

10,当你还在学校的时候,平时有空多看几部白痴一点幼稚一点的片子,比如《流星花园》
那种。当年

我对此嗤之以鼻,现在我一想起一个宿舍的女生围着一台破电脑看它的情景我就鼻子发酸!
!!!现在

我们已经没什么心思能沉在一部片子里耐心地看下去了,偶尔看看电视,就是拿着遥控器拼
命跳台,然

后骂: “tmd!这帮编电视的都狗屎!什么玩意,我要是老板非统统开除了不可,饿死他丫
的!”(ps

:这些话我上大学时听着都脸红,现在越说越溜)

11,当你还在学校的时候,多去上上课,少在宿舍打游戏睡觉。多看看那些底高望重的老教
授,没问题

也找几个出来问问吧,就当小时候听奶奶讲故事。因为,工作以后就不要指望谁这么耐心给
你讲东西了

,老板要是让你做啥,不懂的话千万别问!自己想办法查!不要以为像在学校一样,好问是
美德!你多

问几句,脾气好的老板会不理你,晾着你知道你自己讪讪地走开,脾气稍微不好地老板会对
你阴阴地说

:“你们北大的就这素质?这都不会?”你可能会心里喊冤:“拜托!我接触这项业务才2
天,我不问我

怎么知道?”你这么想就错了。老板要的是结果,不是过程。他管你怎么做到的,总之你做
到了才算完

。我现在每想到大学时候不少次我都在课堂上睡觉,我就觉得特别对不起讲堂上的老师。

12,当你还在学校的时候,能谈恋爱就谈场恋爱,那时候谈恋爱才叫谈恋爱!你的她很可能
只是因为喜

欢你而跟你谈恋爱;你们可能大夏天一起挤公交去动物园,在臭气烘烘的车厢里晃来晃去都
是一种甜蜜

一种幸福;工作以后你就别指望了!如果她跟你谈了3年你还没有能买房能加薪的迹象,你
就完蛋了!如

果你跟她谈了3年你还没有能买房能跟她结婚的迹象,你也完蛋了,你可能会开始怀疑你是
不是在耽误她

的青春她的时间。那时候你们一起再坐公交车,你都会觉得心酸:你堂堂一个北大男子汉,
还要让lp挤

公交车!

13,当你还在学校的时候,多原谅舍友的小过失。不要因为她or他不小心把一杯水泼在你的
英语词典上

就对她or他生气甚至要求赔偿;不要因为她or他的臭袜子忘记从你床上拿走你就对别人抱怨
!不要因为

她or他借了你2块钱买水果一直忘记还就在意。不要不要因为她or他的无意中的缺点或失误
而对他生气。

当你工作以后,你会

发现其实他们原来并没有那么讨厌,你会惊讶当初你干吗总是为这种事情而生气,你会慢慢
忘记他们的

不好而只记得当初你们床头夜话时的温馨、买一包零食回来大家一起吃的开心。当你刚上大
学的时候,

你可能感叹过真心朋友只有在高中才交得到;但当你工作以后你会发现,大学才最可能交到
一辈子的能

互相倾诉互相帮忙的朋友!

14,如果你是女生,当你还在学校的时候,多体谅那些你不喜欢甚至讨厌但是狂追你的男生
!因为无论

你多讨厌他,毕竟他们是真心喜欢你的,在他们眼里,你很可能就是天使!而在工作后,你
在老板看来

,很可能你只不过是狗屎!人的一生中没有多少机会得到一些最真最纯的东西,很多年后那
些看起来又

矮又丑的男生可能结婚成家,你很可能已经被世事磨得没有知觉,而当你再和他们相遇,你
很可能会突

然发现他们原来这么好、这么好、这么这么好,原来他们一点都不丑……你会很想很想哭!

15,当你在学校的时候,多读一点书,少上网做一些没有意义的东西,比如灌水比如聊qq!
因为你一旦

离开校园,你就很可能顶多只有读读《瑞丽》《成都今夜将我遗忘》这样的垃圾杂志和快餐
书,而不再

有机会去想万圣和风入松!更不会有机会有时间有气氛去看那里的书!我在大2的时候,曾
经惊觉我读的

名著基本上停留在高中时代,而当我工作后我发现我读过的书完全停留在大学毕业以前!

16,当你还在学校的时候,不要总是抱怨北大的宿舍太烂太小(虽然这是事实,特别是对于
那些住普通

宿舍的同学)不要总是抱怨楼长阿姨太凶。你不用考虑每个季度有一堆电话水费电费物业费
上网费等等

等等堆在你面前,不用考虑每个季度有房东来催你交房租!不用担心万一你哪天被老板炒鱿
鱼了就要露

宿街头,不用每天下了班回到狭窄而空荡荡的房间痛苦地回想今天是否又挨了骂、明天要计
划拜访哪个

客户、这个case到底哪里让老板不满意……!!!!不用再想说话的时候突然发现竟然想不
起谁可以现

在说说话!!!

17,当你还在学校的时候,你可能为那些该死的偷车贼而痛不欲生咬牙切齿,你可能会在临
上课前5分钟

才起床,然后慢悠悠散步去4教上课;当工作以后,你最大的可能就是每天6点起床,在沙丁
鱼罐头一样

的公交车里焦急地等待你的公交车在堵车长龙里挤牙膏一样一点一点地往前爬;当你因某天
某段路发生

交通事故而迟到了5分钟却因为老板还没来而庆幸时,很可能某个你的亲密同事已经在准备
报告给老板了

。当你晚上再经历同样的堵车回到家想看点书时,你很可能发现时钟已经指到9了,而你这
时候很可能还

没吃饭!

18,如果你是女生,当你还在学校的时候,不要为了减肥而生饿自己把自己弄出胃病来!因
为你会发现

一旦你有了胃病而后工作你会郁闷to death!而且很可能你的工作会导致你不得不得上胃病
,因为你根

本就没时间也没胃口吃任何东西!你在学校的时候,很可能因为某天例假来了而轻易就选择
不去上课,

而当你工作后,哪怕你痛得浑身发凉你也可能强迫自己不请假!因为你要把一年里有限的几
个请假机会

留给你最最需要的时候!在学校的时候,你可能觉得在苗条和健康中你会选择前者,等到你
工作了,你

会发现,健康才是人生最大的财富!因为你的病假越多,你的奖金扣得越多!很可能最后还
会导致你失

业乃至完蛋!

19,当你还在北大的时候,好好念书,享受自己作为北大人的光荣和梦想。因为很可能你工
作以后你会

发现北大人这个牌子不但不是你的盾牌,还很可能成为你收到暗箭的主因。

20,当你还在北大的时候,好好享受人生中最纯洁最快乐的时光!好好享受自己作为一个成
人能够享受

的权利和感觉。因为在你工作满5年之前,你很可能要一直像一条狗一样听人训斥:“你too
naive!too

simple!你在浪费我的时间!”

21,当你还在北大的时候,把英语学好,多学几个软件,修一个经济双学位,多培养自己的
忍耐功夫,

多学点拍mp……少把时间花在理别人攻击北大的言论上,少和他们争论,因为这些都是没有
意义的!有

本事就好好学东西,在你养活自己之前,北大无论是上天堂还是下地狱,都和你没有太大关
系。

22,最后一点:不要再讥笑拜金主义者。不要再相信什么穷人也有骨气。再过几年,你很可
能会悲哀地

发现自己,原来3年前你讥笑的人恰恰正是3年后的自己!人生最大的痛苦,除了穷,就是自
己宣判自己

…… 还在北大的师弟师妹或者师兄师姐,看了这些可能会很难过,但是有些事情,越早知
道以后受的苦

走过的弯路会越少…… 我一直相信我是一个乐观主义者,因为我从来不会因为我外界的原
因而丧失希望

,但是当我想在我的母校的bbs上写下这些东西的时候,我突然发现原来我的心里其实塞了
很多很多令人

难过的东西。也许是因为我从来不会面对活着的东西无论是现实中还是网络中的人抱怨,所
以它们一直

积累一直积累到成为一个角落里的球…… 我依然有梦想,我梦想将来有一套自己的房子,
可以在伤心的

时候一个人泡在浴缸里泡上整整一天,不用在月底的时候心惊肉跳地等着房东上门收租;我
梦想将来有
一天我不用挨骂,不用小心翼翼,不用忍着屈辱每天假笑面对冷冰冰的客户;我梦想将来有
一天我不用

担心我会挨饿会露宿街头会万一我妈妈生病我还付不起昂贵的医药费;我梦想将来有一天我
什么都可以

不想地安然入睡…… 但是我已经没有了理想……

我想这是我最大的悲哀,也是我走向成熟的第一步……

--
是不是该出发了?
--我一直在路上!
不要为了小事情坏了大事情!不值得!
理啊不理你!

※ 来源:·飘渺水云间 freecity.cn·[FROM: vicwzh]
--
※ 转载:·飘渺水云间 freecity.cn·[FROM: proxy1]

[转载] 一个25岁董事长对大学生的精点.....zz

今天穿梭回88,看到几篇文章不错,转过来

发信人: shiyishe (lido), 板面: Optical
标 题: [转载] 一个25岁董事长对大学生的精点.....zz
发信站: 飘渺水云间 (Sun Jan 28 13:21:00 2007), 转信

【 原文由 shiyishe 发表于 ZJUOnline 讨论区 】
1一定要有独立的人格、独立的思想。一个经过独立思考而坚持错误观点的人比一个不假
思索而接受正确观点的人更值得肯定。不要成为灌输教育的牺牲品。

2.仕途,商界,学术。大致说来,每个人都注定要走上三条道路中的某一条。在进行职
业生涯规划的时候,不妨以此作为思考的出发点。根据不同的职业生涯规划来塑造各自
的核心竞争力。只有知道自己以后要做什么,才能知道自己应该学什么。

3.专业无冷热,学校无高低。没有哪个用人单位会认为你代表了你的学校或者你的专业
。千万不要因为你是名牌大学或者热门专业而沾沾自喜,也大可不必因为你的学校不好
或者专业冷门而自卑。

4.千招会,不如一招熟。十个百分之十并不是百分之百,而是零。如果你有十项工作每
项都会做百分之十,那么,在用人单位眼中,你什么都不会。所以,你必须要让自己具
备核心竞争力。“通才”只有在“专才”的基础上才有意义

5.不逃课的学生不是好学生。什么课都不逃,跟什么课都逃掉没什么两样。一定要掌握
学习的主动性,不要像读中学一样被老师牵着鼻子走。逃课没有错,但是不要逃错课。
同时,既要逃课,又要让老师给高分。

6.一定要学会理财。对于贫困生来说,首先要做的不是挣钱,而是省钱。很多大学生读
书的时候一掷千金,可是,毕业以后一个月的工资还不够交半个月的房租。

7.大部分女生将电脑当成了影碟机,大部分男生将电脑当成了游戏机。大学生要掌握必
要的计算机操作能力,但是,很多时候电脑会成为浪费时间的堂而皇之的借口。有电脑
的大学生非常多,可是,这中间很多人可能大学毕业的时候还不会Excel,不会做一个像
样的PPT.

8.做事不如做人,人脉决定成败。一个人有多少钱并不是指他拥有多少钱的所有权,而
是指他拥有多少钱的使用权。一个人具备多少能力,不只是说他一个人的时候能做什么
,还包括他能通过别人做什么。一个人赚的钱,12.5%是靠自身的知识,87.5%则来自人
脉关系。三十岁以前靠专业赚钱,三十岁以后拿人脉赚钱。所以,请好好珍惜大学期间
建立起来的人脉关系。这几年你认识的朋友可能会是你毕业以后最可宝贵的财富。

9.互联网固然威力无穷,但是,如果你沉迷于网络聊天,或者沉迷于网络游戏,浪费的
金钱倒是可以弥补,荒废的青春就无可追寻了。轻舞飞扬已经红颜薄命了,而痞子蔡却
继续跟别的女孩发生着一次又一次的亲密接触。对于很多大学生而言,网吧就是一个血
淋淋的黑洞。

10.爱情是不期而至的,可以期待,但不可以制造。花开堪折方须折,莫让鲜惶哟砜巍?
同时,既要逃课,又要让老师给高分。

6.一定要学会理财。对于贫困生来说,首先要做的不是挣钱,而是省钱。很多大学生读
书的时候一掷千金,可是,毕业以后一个月的工资还不够交半个月的房租。

7.大部分女生将电脑当成了影碟机,大部分男生将电脑当成了游戏机。大学生要掌握必
要的计算机操作能力,但是,很多时候电脑会成为浪费时间的堂而皇之的借口。有电脑
的大学生非常多,可是,这中间很多人可能大学毕业的时候还不会Excel,不会做一个像
样的PPT.

8.做事不如做人,人脉决定成败。一个人有多少钱并不是指他拥有多少钱的所有权,而
是指他拥有多少钱的使用权。一个人具备多少能力,不只是说他一个人的时候能做什么
,还包括他能通过别人做什么。一个人赚的钱,12.5%是靠自身的知识,87.5%则来自人
脉关系。三十岁以前靠专业赚钱,三十岁以后拿人脉赚钱。所以,请好好珍惜大学期间
建立起来的人脉关系。这几年你认识的朋友可能会是你毕业以后最可宝贵的财富。

9.互联网固然威力无穷,但是,如果你沉迷于网络聊天,或者沉迷于网络游戏,浪费的
金钱倒是可以弥补,荒废的青春就无可追寻了。轻舞飞扬已经红颜薄命了,而痞子蔡却
继续跟别的女孩发生着一次又一次的亲密接触。对于很多大学生而言,网吧就是一个血
淋淋的黑洞。

10.爱情是不期而至的,可以期待,但不可以制造。花开堪折方须折,莫让鲜花败残枝。
一个有一万块钱的人为你花掉一百元,你只占了他的百分之一;而一个只有十块钱的人
为你花掉十块,你就成了他的全部。

11.研究生扩招的速度是30%,也就意味着硕士学历贬值的速度是30%。千万不要以为考研
究生就是积极进取的表现。对于很多人而言,考研不过是一种消极逃避的方式罢了。对
于绝大多数人而言,读研究生纯粹是浪费时间浪费金钱,立志从事科研、学术的人及其
他少数人除外

12.不要一门心思想着出国,更加不要迷信外国的月亮比中国圆。削尖脑袋记GRE词汇很
可能是一件非常愚蠢也非常可悲的事情。既然全世界的公司都想到中国的市场上来瓜分
蛋糕,为什么中国人还要一门心思到国外去留学然后给外国人打工?

13.人才市场就是一个地雷阵。通过多种方式求职固然没有错,但是千万不要饥不择食。
只要用人单位一说要你交钱,你掉头就走便是了

14.求职简历必须突出自己的核心竞争力。求职的时候大可不必像严守一那样“有一说一
”,必要的时候恰到好处地说一些谎言是非常有用的。一份求职简历只要用一张A4纸做
个表格就足够了。很多女生的求职简历就像是写真集,不但浪费钱,而且对求职毫无用
处。面试其实是有规律的,每次面试的时候只要背标准答案就行了……

15.垃圾是放错位置的人才。所以,在找工作的时候一定要把自己放到那个让你成为人才
而不是垃圾的职位上。当然,前提是你要知道自己究竟峡罢鄯叫胝郏孟驶ò懿兄Α?
界上最大的悲剧莫过于有太多的年轻人从来没有发现自己真正想做什么。骑驴找马固然
没错,可是,并非随便找一头驴就能找到千里马。所以,一定要重视第一份工作。

16.大公司是做人,小公司是做事。进入公司工作以后,必须尽快融入写字楼政治。职员
能否得到提升,很大程度不在于是否努力,而在于老板对你的赏识程度。在写字楼的政
治斗争中,一定要学会自我保护。


17.瘦死的骆驼比马大。撑死胆大的,饿死胆小的。一定要有创业的勇气和魄力。如果你
一只满足于给别人打工,那么,不管你工资多高,永远都只能是一个可怜的穷光蛋。就
算月薪2万,在深圳上海那种地方,一年的存款还买不来一个小小的洗手间。

18.大学期间一定要多去图书馆多去自习室。很多书你现在不读,一辈子就再也没有机会
去读了。虽然不是每本书看了都一定有用,但是,因为你不知道究竟哪本书以后会有用
,所以只好多看书,并且抛弃那些过于功利的想法。尽管每次网到鱼的不过是一个网眼
,但要想捕到鱼,就必须要编织一张网。


--
爱生活,爱NewAge ^_^

※ 来源:·飘渺水云间 fre,前提是你要知道自己究竟想做什么、究竟适合做什么。世
※ 来源:·飘渺水云间 freecity.cn·[FROM: shiyishe]
--
※ 转载:·飘渺水云间 freecity.cn·[FROM: shiyishe]

Thursday, February 01, 2007

第六章 C++面向对象程序设计

看到了师兄林锐的一篇文章,很遗憾没有早点翻到,走了很多弯路的说。



第六章 C++面向对象程序设计


六年前,我刚热恋“面向对象”(Object-Oriented)时,一口气记住了近十个定义。六年后,我从几十万行程序中滚爬出来准备写点心得体会时,却无法解释什么是“面向对象”,就象说不清楚什么是数学那样。
软件工程中的时髦术语“面向对象分析”和“面向对象设计”,通常是针对“需求分析”和“系统设计”环节的。“面向对象”有几大学派,就象如来佛、上帝和真主用各自的方式定义了这个世界,并留下一堆经书来解释这个世界。
有些学者建议这样找“对象”:分析一个句子的语法,找出名词和动词,名词就是对象,动词则是对象的方法(即函数)。
当年国民党的文人为了对抗毛泽东的《沁园春·雪》,特意请清朝遗老们写了一些对仗工整的诗,请蒋介石过目。老蒋看了气得大骂:“娘希匹,全都有一股棺材里腐尸的气味。”
我看了几千页的软件工程资料,终于发现自己有些“弱智”,无法理解“面向对象”的理论,同时醒悟到“编程是硬道理。”
面向对象程序设计语言很多,如Smalltalk、Ada、Eiffel、Object Pascal、Visual Basic、C++等等。C++语言最讨人喜欢,因为它兼容C语言,并且具备C语言的性能。近几年,一种叫Java的纯面向对象语言红极一时,不少人叫喊着要用Java革C++的命。我认为Java好比是C++的外甥,虽然不是直接遗传的,但也几分象样。外甥在舅舅身上玩耍时洒了一泡尿,俩人不该为此而争吵。
关于C++程序设计的书藉非常多,本章不讲C++的语法,只讲一些小小的编程道理。如果我能早几年明白这些小道理,就可以大大改善数十万行程序的质量了。

6.1 C++面向对象程序设计的重要概念

早期革命影片里有这样一个角色,他说:“我是党代表,我代表党,我就是党。”后来他给同志们带来了灾难。
会用C++的程序员一定懂得面向对象程序设计吗?
不会用C++的程序员一定不懂得面向对象程序设计吗?
两者都未必。就象坏蛋入党后未必能成为好人,好人不入党未必变成坏蛋那样。
我不怕触犯众怒地说句大话:“C++没有高手,C语言才有高手。”在用C和C++编程8年之后,我深深地遗憾自己不是C语言的高手,更遗憾没有人点拨我如何进行面向对象程序设计。我和很多C++程序员一样,在享用到C++语法的好处时便以为自己已经明白了面向对象程序设计。就象挤掉牙膏卖牙膏皮那样,真是暴殄天物呀。
人们不懂拼音也会讲普通话,如果懂得拼音则会把普通话讲得更好。不懂面向对象程序设计也可以用C++编程,如果懂得面向对象程序设计则会把C++程序编得更好。本节讲述三个非常基础的概念:“类与对象”、“继承与组合”、“虚函数与多态”。理解这些概念,有助于提高程序的质量,特别是提高“可复用性”与“可扩充性”。

6.1.1 类与对象
对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么类就是房子的设计图纸。所以面向对象程序设计的重点是类的设计,而不是对象的设计。
类可以将数据和函数封装在一起,其中函数表示了类的行为(或称服务)。类提供关键字public、protected和private用于声明哪些数据和函数是公有的、受保护的或者是私有的。这样可以达到信息隐藏的目的,即让类仅仅公开必须要让外界知道的内容,而隐藏其它一切内容(参见5.2.1节“信息隐藏”)。我们不可以滥用类的封装功能,不要把它当成火锅,什么东西都往里扔。
类的设计是以数据为中心,还是以行为为中心?
主张“以数据为中心”的那一派人关注类的内部数据结构,他们习惯上将private类型的数据写在前面,而将public类型的函数写在后面,如表8.1(a)所示。
主张“以行为为中心”的那一派人关注类应该提供什么样的服务和接口,他们习惯上将public类型的函数写在前面,而将private类型的数据写在后面,如表8.1(b)所示。


Class A
{
private:
int i, j;
float x, y;

public:
void Func1(void);
void Func2(void);

}
class A
{
public:
void Func1(void);
void Func2(void);

private:
int i, j;
float x, y;

}
表8.1(a) 以数据为中心的书写风格 表8.1(b)以行为为中心的书写风格

很多C++教课书主张在设计类时“以数据为中心”。我坚持并且建议读者在设计类时“以行为为中心”,即首先考虑类应该提供什么样的函数。Microsoft 公司的COM规范的核心是接口设计,COM的接口就相当于类的公有函数[Rogerson 1999]。在程序设计方面,咱们不要怀疑Microsoft公司的风格。
设计孤立的类是比较容易的,难的是正确设计基类及其派生类。因为有些程序员搞不清楚“继承”(Inheritance)、“组合”(Composition)、“多态”( Polymorphism)这些概念。

6.1.2 继承与组合
如果A是基类,B是A的派生类,那么B将继承A的数据和函数。示例程序如下:
class A
{
public:
void Func1(void);
void Func2(void);
};

class B : public A
{
public:
void Func3(void);
void Func4(void);
};

// Example
main()
{
B b; // B的一个对象
b.Func1(); // B从A继承了函数Func1
b.Func2(); // B从A继承了函数Func2
b.Func3();
b.Func4();
}

这个简单的示例程序说明了一个事实:C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们要给“继承”立一些使用规则:
一、如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能。不要觉得“白吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。
二、如果类B有必要使用A的功能,则要分两种情况考虑:
(1)若在逻辑上B是A的“一种”(a kind of ),则允许B继承A的功能。如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man可以从类Human派生,类Boy可以从类Man派生。示例程序如下:
class Human
{

};
class Man : public Human
{

};
class Boy : public Man
{

};

(2)若在逻辑上A是B的“一部分”(a part of),则不允许B继承A的功能,而是要用A和其它东西组合出B。例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,不是派生而成。示例程序如下:
class Eye
{ public:
void Look(void);
};
class Nose
{ public:
void Smell(void);
};
class Mouth
{ public:
void Eat(void);
};
class Ear
{ public:
void Listen(void);
};

// 正确的设计,冗长的程序
class Head
{
public:
void Look(void) { m_eye.Look(); }
void Smell(void) { m_nose.Smell(); }
void Eat(void) { m_mouth.Eat(); }
void Listen(void) { m_ear.Listen(); }
private:
Eye m_eye;
Nose m_nose;
Mouth m_mouth;
Ear m_ear;
};

如果允许Head从Eye、Nose、Mouth、Ear派生而成,那么Head将自动具有Look、 Smell、Eat、Listen这些功能:
// 错误的设计
class Head : public Eye, public Nose, public Mouth, public Ear
{
};
上述程序十分简短并且运行正确,但是这种设计却是错误的。很多程序员经不起“继承”的诱惑而犯下设计错误。
一只公鸡使劲地追打一只刚下了蛋的母鸡,你知道为什么吗?
因为母鸡下了鸭蛋。
本书3.3节讲过“运行正确”的程序不见得就是高质量的程序,此处就是一个例证。

6.1.3 虚函数与多态
除了继承外,C++的另一个优良特性是支持多态,即允许将派生类的对象当作基类的对象使用。如果A是基类,B和C是A的派生类,多态函数Test的参数是A的指针。那么Test函数可以引用A、B、C的对象。示例程序如下:
class A
{
public:
void Func1(void);
};

void Test(A *a)
{
a->Func1();
}

class B : public A
{

};
class C : public A
{

};

// Example
main()
{
A a;
B b;
C c;
Test(&a);
Test(&b);
Test(&c);};

以上程序看不出“多态”有什么价值,加上虚函数和抽象基类后,“多态”的威力就显示出来了。
C++用关键字virtual来声明一个函数为虚函数,派生类的虚函数将覆盖(override)基类对应的虚函数的功能。示例程序如下:
class A
{
public:
virtual void Func1(void){ cout<< “This is A::Func1 \n”}
};

void Test(A *a)
{
a->Func1();
}

class B : public A
{
public:
virtual void Func1(void){ cout<< “This is B::Func1 \n”}
};
class C : public A
{
public:
virtual void Func1(void){ cout<< “This is C::Func1 \n”}
};

// Example
main()
{
A a;
B b;
C c;
Test(&a); // 输出 This is A::Func1
Test(&b); // 输出 This is B::Func1
Test(&c); // 输出 This is C::Func1};

如果基类A定义如下:
class A
{
public:
virtual void Func1(void)=0;
};
那么函数Func1叫作纯虚函数,含有纯虚函数的类叫作抽象基类。抽象基类只管定义纯虚函数的形式,具体的功能由派生类实现。
结合“抽象基类”和“多态”有如下突出优点:
(1)应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。这一招叫“以不变应万变”,可以大大提高程序的可复用性(这是接口设计的复用,而不是代码实现的复用)。
(2)派生类的功能可以被基类指针引用,这叫向后兼容,可以提高程序的可扩充性和可维护性。以前写的程序可以被将来写的程序调用不足为奇,但是将来写的程序可以被以前写的程序调用那可了不起。

6.2 良好的编程风格

内功深厚的武林高手出招往往平淡无奇。同理,编程高手也不会用奇门怪招写程序。良好的编程风格是产生高质量程序的前提。

6.2.1 命名约定
有不少人编程时用拼音给函数或变量命名,这样做并不能说明你很爱国,却会让用此程序的人迷糊(很多南方人不懂拼音,我就不懂)。程序中的英文一般不会太复杂,用词要力求准确。
匈牙利命名法是Microsoft公司倡导的 [Maguire 1993],虽然很烦琐,但用习惯了也就成了自然。没有人强迫你采用何种命名法,但有一点应该做到:自己的程序命名必须一致。
以下是我编程时采用的命名约定:
(1)宏定义用大写字母加下划线表示,如MAX_LENGTH;
(2)函数用大写字母开头的单词组合而成,如SetName, GetName ;
(3)指针变量加前缀p,如 *pNode ;
(4)BOOL 变量加前缀b,如 bFlag ;
(5)int 变量加前缀i,如 iWidth ;
(6)float 变量加前缀f,如 fWidth ;
(7)double变量加前缀d,如 dWidth ;
(8)字符串变量加前缀str,如 strName ;
(9)枚举变量加前缀e,如 eDrawMode ;
(10)类的成员变量加前缀m_,如 m_strName, m_iWidth ;
对于 int, float, double 型的变量,如果变量名的含义十分明显,则不加前缀,避免烦琐。如用于循环的int型变量 i,j,k ;float 型的三维坐标(x,y,z)等。

6.2.2 使用断言
程序一般分为Debug版本和Release版本,Debug版本用于内部调试,Release版本发行给用户使用。
断言assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生的情况。以下是一个内存复制程序,在运行过程中,如果assert的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。
//复制不重叠的内存块
void memcpy(void *pvTo, void *pvFrom, size_t size)
{
void *pbTo = (byte *) pvTo;
void *pbFrom = (byte *) pvFrom;
assert( pvTo != NULL && pvFrom != NULL );
while(size - - > 0 )
*pbTo + + = *pbFrom + + ;
return (pvTo);
}
assert不是一个仓促拼凑起来的宏,为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。
很少有比跟踪到程序的断言,却不知道该断言的作用更让人沮丧的事了。你化了很多时间,不是为了排除错误,而只是为了弄清楚这个错误到底是什么。有的时候,程序员偶尔还会设计出有错误的断言。所以如果搞不清楚断言检查的是什么,就很难判断错误是出现在程序中,还是出现在断言中。幸运的是这个问题很好解决,只要加上清晰的注释即可。这本是显而易见的事情,可是很少有程序员这样做。这好比一个人在森林里,看到树上钉着一块“危险”的大牌子。但危险到底是什么?树要倒?有废井?有野兽?除非告诉人们“危险”是什么,否则这个警告牌难以起到积极有效的作用。难以理解的断言常常被程序员忽略,甚至被删除。[Maguire 1993]
以下是使用断言的几个原则:
(1)使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。
(2)使用断言对函数的参数进行确认。
(3)在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。
(4)一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。

6.2.3 new、delete与指针
在C++中,操作符new用于申请内存,操作符delete用于释放内存。在C语言中,函数malloc用于申请内存,函数free用于释放内存。由于C++兼容C语言,所以new、delete、malloc、free都有可能一起使用。new能比malloc干更多的事,它可以申请对象的内存,而malloc不能。
C++和C语言中的指针威猛无比,用错了会带来灾难。对于一个指针p,如果是用new申请的内存,则必须用delete而不能用free来释放。如果是用malloc申请的内存,则必须用free而不能用delete来释放。
在用delete或用free释放p所指的内存后,应该马上显式地将p置为NULL,以防下次使用p时发生错误。示例程序如下:
void Test(void)
{
float *p;
p = new float[100];
if(p==NULL) return;
…// do something
delete p;
p=NULL; // 良好的编程风格

// 可以继续使用p
p = new float[500];
if(p==NULL) return;
…// do something else
delete p;
p=NULL;
}

我们还要预防“野指针”,“野指针”是指向“垃圾”内存的指针,主要成因有两种:
(1)指针没有初始化。
(2)指针指向已经释放的内存,这种情况最让人防不胜防,示例程序如下:
class A
{
public:
void Func(void){…}
};
void Test(void)
{
A *p;
{
A a;
p = &a; // 注意 a 的生命期
}
p->Func(); // p是“野指针”,程序出错
}

6.2.4 使用const
在定义一个常量时,const比 #define更加灵活。用const定义的常量含有数据类型,该常量可以参与逻辑运算。例如:
const int LENGTH = 100; // LENGTH是int类型
const float MAX=100; // MAX是float类型
#define LENGTH 100 // LENGTH 无类型
#define MAX 100 // MAX 无类型

除了能定义常量外,const还有两个“保护”功能:
一、强制保护函数的参数值不发生变化
以下程序中,函数f不会改变输入参数name的值,但是函数g和h都有可能改变name的值。
void f(String s); // pass by value
void g(String &s); // pass by referance
void h(String *s); // pass by pointer
main()
{
String name=“Dog”;
f(name); // name的值不会改变
g(name); // name的值可能改变
h(name); // name的值可能改变
}

对于一个函数而言,如果其‘&’或‘*’类型的参数只作输入用,不作输出用,那么应当在该参数前加上const,以确保函数的代码不会改变该参数的值(如果改变了该参数的值,编译器会出现错误警告)。因此上述程序中的函数g和h应该定义成:
void g(const String &s);
void h(const String *s);

二、强制保护类的成员函数不改变任何数据成员的值
以下程序中,类stack的成员函数Count仅用于计数,为了确保Count不改变类中的任何数据成员的值,应将函数Count定义成const类型。
class Stack
{
public:
void push(int elem);
void pop(void);
int Count(void) const; // const类型的函数
private:
int num;
int data[100];
};

int Stack::Count(void) const
{ ++ num; // 编译错误,num值发生变化
pop(); // 编译错误,pop将改变成员变量的值
return num;
}

6.2.5 其它建议
(1)不要编写一条过分复杂的语句,紧凑的C++/C代码并不见到能得到高效率的机器代码,却会降低程序的可理解性,程序出错误的几率也会提高。
(2)不要编写集多种功能于一身的函数,在函数的返回值中,不要将正常值和错误标志混在一起。
(3)不要将BOOL值TRUE和FALSE对应于1和0进行编程。大多数编程语言将FALSE定义为0,任何非0值都是TRUE。Visual C++将TRUE定义为1,而Visual Basic则将TRUE定义为-1。示例程序如下:
BOOL flag;

if(flag) { // do something } // 正确的用法
if(flag==TRUE) { // do something } // 危险的用法
if(flag==1) { // do something } // 危险的用法
if(!flag) { // do something } // 正确的用法
if(flag==FALSE) { // do something } // 不合理的用法
if(flag==0) { // do something } // 不合理的用法

(4)小心不要将“= =”写成“=”,编译器不会自动发现这种错误。
(5)不要将123写成0123,后者是八进制的数值。
(6)将自己经常犯的编程错误记录下来,制成表格贴在计算机旁边。

6.3 小 结

C++/C程序设计如同少林寺的武功一样博大精深,我练了8年,大概只学到二三成。所以无论什么时候,都不要觉得自己的编程水平天下第一,看到别人好的技术和风格,要虚心学习。
本章的内容少得可怜,就象口渴时只给你一颗杨梅吃,你一定不过瘾。我借花献佛,推荐一本好书:Marshall P. Cline著的《C++ FAQs》[Cline 1995]。你看了后一定会赞不绝口。
会编写C++/C程序,不要因此得意洋洋,这只是程序员基本的技能要求而已。如果把系统分析和系统设计比作“战略决策”,那么编程充其量只是“战术”。如果指挥官是个大笨蛋,士兵再勇敢也会吃败仗。所以我们程序员不要只把眼光盯在程序上,要让自己博学多才。我们应该向北京胡同里的小孩们学习,他们小小年纪就能指点江山,评论世界大事。