Profil von 小小星点仍会有玫瑰FotosBlogListenMehr Extras Hilfe
Foto 1 von 18

18 Januar

两个喜欢唱歌的校长

今天在sina上看新闻的时候发现了一个视频,北大徐智宏校长在北大08新年联欢会上唱隐性的翅膀(http://you.video.sina.com.cn/b/10638307-1298312820.html)
 
然后突然想到了重大喜欢唱歌的李晓红校长,然后也就突然明白了北大和重大在文化气质上的巨大差异。
 
不过我们有滨江路,北大有么....灭哈哈哈哈哈哈哈
我们有吃一次拉一次肚子的六食堂,北大有么....
 
 
 
 
 
 
28 November

倍受刺激的重庆之行

1. 修了四年的红旗河沟终于修好了
2. 重大几乎没什么变化
3. 惠普两个小白领的生活很好很强大
4. 重庆的房价跟北京的白菜持平
5. 火锅还是很好吃
6. 生病的时候有人帮忙吃药也是一件十分幸福的事情
7. 某正太和某萝莉很和谐很强大
8. 终于实现了在南滨路吃饭的伟大理想
9. 南苑机场很好很强大
 
以上
12 November

周期性发作的自闭症患者

以上。
 
另,安得广厦千万间.....
 
周末去园子...
25 September

所谓西江月·中秋 星点点陛下中秋草作....其实应该是御作...

艳阳不对秋景

晴天难入文章

帝都万里气高爽

晚月低照残凉

 

才子佳人纨手

刘伶得意张狂

雕栏不语笑盈房

袅袅芙蓉形状

 

何怀知己对饮

再邀七八同窗

茗翠月璃桂花香

随品但赏且尝

 

密林难见树影

小桥不伴池塘

桃花流水古时样

卷走离人匆忙

 

中秋嫦娥奔月

端午屈原赴江

问君此时何思量

惊开休生死伤

 

佳节不看历法

但须景美辰良

愿天生得慈悲肠

赐我一个无双………..

 
11 Juli

星点点陛下和蚊子双方互利友好双边协议

甲方:星点点陛下
乙方:蚊子

合约条款

一,甲方义务

为保证乙方的生存空间,经过双方彻夜友好协商,达成以下共识:

甲方不得购买、使用威胁乙方生命财产安全的非自然物品,包括但不限于:杀虫剂,蚊香,电蚊香,粘蚊纸,诱蚊灯

甲方不得饲养乙方的天敌作为宠物,包括但不限于:青蛙,蜘蛛,蟾蜍,蜻蜓

甲方有义务为乙方提供生存必要的空间、食物,并允许乙方根据自己口味自由选择食物种类,如乙方不选择甲方提供的食物,甲方有义务保护乙方的自由择食权

甲方可以自由洗澡、使用自己喜爱的附属物品,但不得与前面条款抵触

二:乙方的义务和权利

乙方必须在甲方指定的区域内进食,不得叮咬手脚等影响正常活动部位,不得叮咬面部,不得擅自向甲方索吻,未经甲方同意,严禁擅自为甲方口  交

乙方进食过程中需保持安静,不得影响甲方睡眠,如遇到甲方心情不好时误伤乙方致死,甲方不负违约责任

乙方不得结帮拉派,未经甲方同意,严禁于甲方控制的区域内繁殖后代,乙方的自由进食权不世袭,不转让。

乙方对甲方购买的水果和零食不得表现出任何兴趣,否则甲方误伤乙方致死,甲方不承担违约责任

乙方在甲方非睡眠时间,不得擅自行动,如因此甲方误伤乙方致死,甲方不承贷违约责任

乙方需签订终身合约,在享受甲方提供的优惠条款时,不得与第三方产生任何关系,乙方有保护甲方不受传染病危害的义务。

三,违约及惩罚

以上条款,任意一方违反均视为条约失效,自条约失效日起,双方不再承担合同中规定的义务责任。

四,附则

星点点陛下保留该协议的修改权和解释权,并无义务告会乙方

五,此条例自公布之日起施行
15 März

[童话]我们都太执着于自己

起初

那年,你离开
在河边种下一棵玫瑰树
只为我开花
于是,我守侯
从它发芽到长大
却始终都只看到满眼的碧绿。。



我知道自己的使命
我努力的生长
看到自己在长高
看到那由嫩红变的浅绿
再长成翡翠一样的叶
我多爱它
甚至放弃了开花
怕花儿抢走了它的养分
怕它枯黄。。
可是,我发现它在等待
等待那迟迟未到的花
于是,我长出花苞




我奋力的长大
想为将开的花儿撑开一把保护伞
多想就一直把它藏起来
可我知道有人在等它
已经很久很久了的等待
最终,我离去




终于看清它了
在水中,在众多的绿色中
独一无二的红
多美
我使劲挣脱,向它飘飞
可到了水面才发现
那一直爱着的
原来,就是自己




拥抱着它,触摸着它
我惊喜的不知所措
可是,我看到了它的孤独
水,不是它的家
于是,我将它送上岸
求泥土延续它的美丽




它来了
带来了一朵枯萎的花又匆匆离去
我没有挽留
也留不住那纯净的生命
我太平凡了
会让它蒙尘,变得污浊不清
那朵残花,我把他交给一只毛毛虫
请它带它到树上去
那儿,才是它的家




我努力的拽着死去的花儿往上爬
多舍不得,多贪恋它的怀抱
可我现在得走了
去完成它的心愿
一只鸟看到了我
我笑,就这样死去,也好




我知道不该的
可还是不可救药的爱上它
小小的,毛茸茸的
开心的在大地上爬来爬去
是那么的纯真可爱
再等待吧,等它化为最美的蝶




破茧而出
好奇的看这个全新的世界
记忆?怎么都变的模糊不清?
在晨光中展开翅膀
我看到一颗闪亮的露珠
在叶尖上颤抖,流转
多纯洁的生灵啊
我开心的为它起舞




终于凝结了
从飘散的雾变成了露珠
停在它身上
我知道这么做会毁了自己
但已经无所谓了
小草啊,你醒了吗?
阳光不允许我再停留了




在晨光中苏醒
我开心的抖动叶子
刚才好象有谁在叫我
看看四周,咦?
那只每天停在树梢
一直凝望地面的鸟儿怎么不见了。。




终于看到它化为天使了
好美
可是,它却守侯一颗露珠
最终因为它的消逝而心碎
永远留在了地面。。
我带着它离开
飞到遥远的北方
听说,那儿的露会冻结成冰
久久不化
它一定会很开心




来了一只鸟,带着只死去的蝶
守着它日日哀鸣
终于,在一个寒夜过后
倒在了我怀里
再没醒来
我看到我的心开始复苏,在痛
我惊慌起来,请求雪帮我将它埋葬




冰叫我了
要我帮它掩埋一只死去的鸟
多傻
那样做,也会把自己埋葬了的
可我不忍心拒绝
于是求云放我离开




它终于要走了
这一去,就再不会回来了
还是没阻止
我只希望它能开心
托风帮我送它一程
真怕它会在途中迷了路




它今天很伤心
变的灰蒙蒙的
我知道,是因为雪的离去
不忍心看它这样
我答应了它的请求
趁着微弱的月光,带走了雪




又见到它了
在雪花中呼啸悲鸣
不该啊,它是快乐自由的风啊
撒下一束光,托它帮我看望那忧伤的风儿




离开月,去帮它追寻风
可是我失职了
我在一块石头上停了下来
和它一起静静的守侯一棵枯死的玫瑰树
它告诉我,它在等它开花
花开了,它的爱人就会回来了




我知道花已经开过了
也知道不会再开了
可仍然守侯
也许,等待,已经成了我的习惯吧
有一束月光走过,停了下来
说要陪伴我
我笑
到了天明,还不是要离开


结束

“妈妈,什么是结束啊?”
“结束呀,就是把两个人的头发结成一束,那样他们就不会分开了。。”
“哦。。。那爸爸和妈妈也结束了,是吗?”
“是啊,结束了。。。。”

让小I机器人打败了

小i机器人 说:
你觉得同性恋者会有幸福吗?
 
小点点陛下 说:
小i机器人 说:
我不是很看好哦,因为这似乎不太科学哦
小点点陛下 说:
为什么呢
小i机器人 说:
不为什么~因为我就是
小点点陛下 说:
...
 
 
另,小I机器人的MSN:ince291@hotmail.com
09 Januar

公车DS艳遇

我真傻,真的。我单知道在住的地方大家无聊,会拿DS来玩;我不知道公车上也会有。我一清早上班坐车,拿DS玩了一局找茬,叫售票员撕了一张票给我,他是很听话的,只要给了钱就能拿到票。他到前面去了,我就在座位上开机,加载,开玩。玩到一半,一个MM过来问我玩的是什么,我说找茬,她就和我联机打了一局马车,我使用了各种无耻的手段(故意不吃道具,故意撞香蕉皮)让MM赢了,我一急,就要跟她联任天狗,结果死机了,M3卡是不容易死机的,到网上一看,果然是内核的问题。下车之后,说过byebye就走了。她果然素个乖巧的loli,粉红色的DS,上面贴着牧场无语的贴纸,可是我居然忘记找她要电话了……
01 Januar

江城子@元旦

张原海问我,元旦短信怎么发,我说随便,他说有没有什么宋词,我沉默。然后他在那里:十年生死两苍茫。我当时就旷了。等清醒过来的时候,手机上多了一些下面的字:

京城飞雪瑞吉祥

月盈亏

天翱茫

温衣暖床

岁守末华章

一骑绝尘江南北

尚安泰

加班狂

 

晓夜微火暗阁窗

年增寿

人添长

更早迭晚

空随叹儿郎

恨君时节风华茂

半偷欢

花满房

 

然后全选电话簿,然后群发....

然后电话就欠费了

 

这个故事告诉我们,以前的文人穷困潦倒是有原因的。

 

so,在今年的第一天,用这种便宜的方式,祝大家新年快乐

 

遗失的美好也不再是美好,一切在06年丢掉的获得的沮丧的振奋的都要统统打包,带进07年的,是一切舒妙的元素。

 

当然,还有曼联夺冠。

江城子@元旦

张原海问我,元旦短信怎么发,我说随便,他说有没有什么宋词,我沉默。然后他在那里:十年生死两苍茫。我当时就旷了。等清醒过来的时候,手机上多了一些下面的字:

京城飞雪瑞吉祥

月盈亏

天翱茫

温衣暖床

岁守末华章

一骑绝尘江南北

尚安泰

加班狂

 

晓夜微火暗阁窗

年增寿

人添长

更早迭晚

空随叹儿郎

恨君时节风华茂

半偷欢

花满房

 

然后全选电话簿,然后群发....

然后电话就欠费了

 

这个故事告诉我们,以前的文人穷困潦倒是有原因的。

 

so,在今年的第一天,用这种便宜的方式,祝大家新年快乐

 

遗失的美好也不再是美好,一切在06年丢掉的获得的沮丧的振奋的都要统统打包,带进07年的,是一切舒妙的元素。

 

当然,还有曼联夺冠。

25 Dezember

听我的闲言碎语吧

冷风

冷风吹

 

闻滨和张原海告诉我这是古龙的特有风格,顺便也鄙视了一下从来没有完整看过一部武侠小说的我。高中都是在上课的时候看书,只不过人家看的是武侠,我看的是余秋雨、村上春树、周作人、梁秋实、卡夫卡、昆德拉、王尔德、余华、康德和叔本华。时间就这样被我可耻的浪费了,现在想起来,当时以为清高雅致的东西没有给我带来任何实用性的好处,反而让我丧失了承受现实的勇气。张大款说有时候看看YY文学也是释放压力的好办法,甚以为然。

 

汪洋补牢行动,然后我就发现自己越来越被目的所驱使,阅读快感是我现在的第一原动力,科幻译文版的某期编辑说,要弘扬读书无用论,甚以为然。

 

说到目的性就不免要扯一下我现在的工作,多线程...万恶的多线程,从这点上大刘三体的硬伤是很明显的,因为那个智子不可能有多余的信号量来保持事件的互斥和同步。也就是说,只要那些粒子加速器在严格意义上的时间一致,智子就会导致死锁。当然,它死锁不死锁跟我关系不大,问题是我现在死锁了。本来多线程就够受了,再加上一个不可预测的网络双工,恩恩,一切理论都是灰色的,唯有生命之树常青。甚以为然。

 

加班,加班,无尽的任务...但我明明是玩wow的啊,EQ看到界面就把我吓跑了。我的梦想是当一个兽人盗贼,整天去灰谷猥亵的看着那些年青的NE MM...被发现就跑到奥格瑞马,萨尔不管我我就把他和吉安娜的八卦贴到智慧谷的门口。人心险恶啊,齐宣王说谁都得防着,甚以为然。

 

过度的逻辑思维就会导致倾诉的欲望过于强烈,特别是对于自闭两个极端的我。一直都在拷问自己到底要过上什么样的生活,得到的答案往往繁琐不堪且喋喋不休。WinProc函数告诉我们,如果非要处理每个MOUSE_MOVE消息,整个程序的消息循环就会阻塞,甚以为然。

 

那是一个挥之不去的阴影,是埋藏在柳树下的冤魂,是挂在杨絮种子上的七色彩光,是古墓幽森的卡拉ok。没有美的意境,却充满美的因素,喜怒忧思悲恐惊,七情,生死耳目口鼻,六欲,文字收敛的东西,再平常也会觉得高深无比。特德蒋说人类的语言和文字是某种意义上的多此一举,甚以为然。

 

午饭是我最为发愁的一个问题,每天都不知道吃什么,于是选择干脆不吃,然后到下午四五点钟忍受手脚发麻全身冰凉,越来越讨厌为这些事情发愁,而下班在公车上脑子里面唯一清醒的意识就是到哪里下车。上帝是慈悲的,给了我每天30分钟的时间来接受工作的开始和从工作状态中恢复。程序员是体力活么?甚以为然。

 

不管怎样一天还是跟着一天,我不知道什么时候是个尽头,我不知道什么时候会有个改变,我不喜欢一成不变的安稳,我想找风口浪尖的快感。卡马克说,计算机图形学已经让他找不到挑战,于是他去玩火箭了。甚以为然。

 

好了,反反复复的话就说到这里吧。楠楠说想太多容易掉头发,甚以为然

22 Dezember

马季先生千古

自由化五天同学在MSN上问我,马季死了?心中一惊,不情愿的打开百度,然后搜索马季。果然,醒目的标题,姜昆证实马季先生去世,时间是今天,就在我写下这些文字的三个小时前。

 

似乎应该感谢网络和无孔不入的媒体,能让我在马季先生体温犹存的时候献上这微不足道的祭奠。坦白的说我并非多么喜爱马季的作品和表演,他的新相声论,也或多或少的扼杀了相声的另一条支脉。越来越多的歌功颂德,粉饰太平,让相声变成了对口的新闻联播,而他的诸多弟子也逐渐成为了电视相声的熟人熟脸,然后纷纷离开相声界,主持,影视,小品诸如此类。功过是非,我无权评述,逝者不灭,这是无比残酷的家族箴言。

 

宇宙牌香烟是我最早有印象的单口相声,那个时候的春晚,远远比现在要丰盛很多,缺少了外在效果的包装,反而演员们拿出的都是实打实的东西。刚刚4、5岁的我笑得喘不过气来,在那个快乐元素极度缺乏的年代,电视上的相声是我唯一的期盼。然后我听到了学聋哑,口吐莲花,买布头,那台小小的收音机,慢慢的带我进入了相声的一片汪洋。

 

我那个时候不知道什么叫包袱,什么叫贯口,什么叫逗哏,什么叫量活,什么叫垫话,什么叫打哏,但是那个时候的快乐却是真实而纯粹的。现在我可以轻而易举的用这些符号分析离散,却再也找不到那时候毫无理由的笑声。

 

现在回忆的时候,我十分庆幸的是我居然拥有这样的一个童年,在大多数同龄人都在街机上拼得你死我活时,我和爷爷躺在火热的炕上,听着不甚清楚的中波广播,相声、评剧、大鼓、评书,丝毫意识不到在听完侯宝林的段子之后再听一段刘宝瑞的单口是多么奢侈的事情。

 

多事之秋,多事之秋。

 

郭德纲说,我爱相声,我怕它完了。我相信他是真诚的。我也一直认为,相声本身就是对人类的自嘲,无论捧逗,他们在台上都是一体的,他们把可笑的一面赤裸裸的呈现出来,然后反身自问。相声总有底活,但人生没有。喜欢听相声的人大多都是善良而清醒的,他们可以看到自己身上的一切不足而且可以忍受它,相声圈内的是是非非我没有资格说什么,但我只喜欢让我笑的相声,我也爱相声,我也怕它完了。

 

相声是中国北方曲艺的百科大全,是汉语方言的全局索引,是中国历史的书签目录,是整个人类的生活轨迹。

 

马季先生千古,愿天堂充满欢笑。

终于登上来了

....太久没有更新了,不是我懒,公司没办法上MSN Spacse
 
没时间写什么东西了,贴点在校内网贴过的吧
本人精通:

吹拉弹唱、唱念做打;
望闻问切、煎炒烹炸;
说学逗唱、搓澡桑拿;
刀枪剑戟、斧钺钩叉;
吃喝嫖赌、琴棋书画、
坑蒙拐骗、撬锁拔牙;
善于抽射、点球专家;
会写程序,VC++;
诗词歌赋、大小擒拿;
南腔北调、杰伦阿雅;
跳水体操、样样俱佳;
疏通管道、维修电话;
航天科技,克隆青蛙;
哲学思辨、裁剪大褂;
缝补被褥,锻造铠甲。
网游代练、倒水端茶;
当海贼王,救雅典娜;
挖始皇坟,偷烤鸡架;
指挥交通、相面算卦。
天文地理,捉鱼抓虾。
葵花点穴,独霸武侠。
排山倒海,芙蓉掌法。
钢琴小号,二胡唢呐。
笙管笛箫,风琴琵琶。
抢人玉米,偷人地瓜。
平定社稷,振兴国家。
舞狮驯兽、十样杂耍;
祥瑞福云、口吐莲花;
增财送子、索命绑架。
导演编剧、龙套打杂;
四级枪手、卖报送花;
奸淫掳掠,坐地起价;
打屋劫舍,扶助孤寡;
清洁卫生,拆房搬家;
运筹帷幄,杀人如麻;
铺设地板、擦鞋打蜡;
汽车喷漆、替人挨骂;




我还真是一个全面的人才....


有兼职请联系我...不会让你们失望滴.....
18 Oktober

论C++构造函数中的不合理设计

论C++构造函数中的不合理设计
作者:张岩  


  在C++中,构造函数是一个在构件对象的时候调用的特殊的函数,其目的是对对象进行初始化的工作,从而使对象被使用之前可以处于一种合理的状态。但是,构造函数的设计并不完美,甚至有些不合理的特性。比如说,限定构造函数名称与类的名称相同的条件。这些特性在构造C++编译器的时候是值得引起注意的。还有,在今后C++的标准修订或者制定其他面向对象的设计语言时候应当避免这些特性。这里也提出了一些解决的方案。
  C++中,任何类都有一个(至少有一个)构造函数,甚至在没有构造函数被声明的时候亦是如此。在对象被声明的时候,或者被动态生成的时候,这些构造函数就会被调用。构造函数做了许多不可见的工作,即使构造函数中没有任何代码,这些工作包括对对象的内存分配和通过赋值的方式对成员进行初始化。构造函数的名称必须与类的名称相同,但是可以有许多不同的重载版本来提供,通过参数类型来区分构造函数的版本。构造函数可以显式的通过用户代码来调用,或者当代码不存在是通过编译程序来隐式插入。当然,显式地通过代码调用是推荐的方法,因为隐式调用的效果可能不是我们所预料的,特别是在处理动态内存分配方面。代码通过参数来调用唯一的构造函数。构造函数没有返回值,尽管在函数体中可以又返回语句。每个构造函数可以以不同的方式来实例化一个对象,因为每个类都有构造函数,至少也是缺省构造函数,所以每个对象在使用之前都相应的使用构造函数。构造函数的调用如图1所示。

图1. The activities involved in the execution of a constructor

  因为构造函数是一种函数,所以他的可见性无非是三种public、private、protected。通常,构造函数都被声明为public型。如果构造函数被声明为private或protected,就限制了对象的实例化。这在阻止类被其他人实例化的方面很有效。构造函数中可以有任何C++的语句,比如,一条打印语句,可以被加入到构造函数中来表明调用的位置。


构造函数的类型

  C++中构造函数有许多种类型,最常用的式缺省构造函数和拷贝构造函数,也存在一些不常用的构造函数。下面介绍了四种不同的构造函数。

1、缺省构造函数
  缺省构造函数是没有参数的函数。另外,缺省构造函数也可以在参数列表中以参数缺省值的方式声明。缺省构造函数的作用是把对象初始化为缺省的状态。如果在类中没有显式定义构造函数,那么编译器会自动的隐式创建一个,这个隐式创建的构造函数和一个空的构造函数很相像。他除了产生对象的实例以外什么工作都不做。在许多情况下,缺省构造函数都会被自动的调用,例如在一个对象被声明的时候,就会引起缺省构造函数的调用。

2、拷贝构造函数
  拷贝构造函数,经常被称作X(X&),是一种特殊的构造函数,他由编译器调用来完成一些基于同一类的其他对象的构件及初始化。它的唯一的一个参数(对象的引用)是不可变的(因为是const型的)。这个函数经常用在函数调用期间于用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。
  在C++中,下面三种对象需要拷贝的情况。因此,拷贝构造函数将会被调用。
  1). 一个对象以值传递的方式传入函数体
  2). 一个对象以值传递的方式从函数返回
  3). 一个对象需要通过另外一个对象进行初始化
  以上的情况需要拷贝构造函数的调用。如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作赋共同实现的。描述拷贝构造函数和赋值运算符的异同的参考资料有很多。
  拷贝构造函数不可以改变它所引用的对象,其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,它的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环。
  除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。换句话说,你从函数返回得到的只是对象的一份拷贝。但是同样的,拷贝构造函数被正确的调用了,你不必担心。
  如果在类中没有显式的声明一个拷贝构造函数,那么,编译器会私下里为你制定一个函数来进行对象之间的位拷贝(bitwise copy)。这个隐含的拷贝构造函数简单的关联了所有的类成员。许多作者都会提及这个默认的拷贝构造函数。注意到这个隐式的拷贝构造函数和显式声明的拷贝构造函数的不同在于对于成员的关联方式。显式声明的拷贝构造函数关联的只是被实例化的类成员的缺省构造函数除非另外一个构造函数在类初始化或者在构造列表的时候被调用。
  拷贝构造函数是程序更加有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。设计拷贝构造函数是一个良好的风格,即使是编译系统提供的帮助你申请内存默认拷贝构造函数。事实上,默认拷贝构造函数可以应付许多情况。

3、用户定义的构造函数
  用户定义的构造函数允许对象在被定义的时候同时被初始化。这种构造函数可以有任何类型的参数。一个用户定义的和其它类型的构造函数在类 mystring 中得以体现:

  class mystring
  {......
  public: mystring(); // Default constructor
  mystring (mystring &src)
  // Copy constructor
  mystring (char * scr);
  // Coercion constructor
  mystring ( char scr[ ], size_t len);
  // User-Defined constructor

  };


4、强制构造函数
  C++中,可以声明一个只有一个参数的构造函数来进行类型转换。强制构造函数定一个从参数类型进行的一个类型转换(隐式的或显式的)。换句话说,编译器可以用任何参数的实例来调用构造函数。这样做的目的是建立一个临时实例来替换一个参数类型的实例。注意标准新近加入C++的关键字explicit 是用来禁止隐式的类型转换。然而,这一特性还没能被所有的编译器支持。下面是一个强制构造函数的例子:


  class A
  {
  public :
  A(int ){ }
  };
  void f(A) { }
  void g()
  {
  A My_Object= 17;
  A a2 = A(57);
  A a3(64);
  My_Object = 67;
  f(77);
  }

  像A My_Object= 17;这种声明意味着A(int)构造函数被调用来从整型变量生成一个对象。这样的构造函数就是强制构造函数。


普遍特性

  下面是一些C++构造函数的不合理设计,当然,可能还有其他一些不合理之处。但是,大多数情况下,我们还是要和这些特性打交道,我们要逐一说明。

1、构造函数可以为内联,但不要这样做
  一般来讲,大多数成员函数都可以在前面加入"inline"关键字而成为内联函数,构造函数也不例外,但是别这么做!一个被定义为内联的构造函数如下:

  class x
  {..........
  public : x (int );
  :
  :
  };
  inline x::x(int )
  {...}

  在上面的代码中,函数并不是作为一个单独的实体而是被插入到程序代码中。这对于只有一两条语句的函数来说会提到效率,因为这里没有调用函数的开销。
  用内联的构造函数的危险性可以在定义一个静态内联构造函数中体现。在这种情况下,静态的构造函数应当是只被调用一次。然而,如果头文件中含有静态内联构造函数,并被其他单元包括的话,函数就会产生多次拷贝。这样,在程序启动时就会调用所有的函数拷贝,而不是程序应当调用的一份拷贝。这其中的根本原因是静态函数是在以函数伪装下的真实对象。
  应该牢记的一件事是内联是建议而不是强制,编译器产生内联代码。这意味着内联是与实现有关的编译器的不同可能带来很多差异。另一方面,内联函数中可能包括比代码更多的东西。构造函数被声明为内联,所有包含对象的构造函数和基类的构造函数都需要被调用。这些调用是隐含在构造函数中的。这可能会创建很大的内联函数段,所以,不推荐使用内联的构造函数。

2、构造函数没有任何返回类型
  对一个构造函数指定一个返回类型是一个错误,因为这样会引入构造函数的地址。这意味着将无法处理出错。这样,一个构造函数是否成功的创建一个对象将不可以通过返回之来确定。事实上,尽管C++的构造函数不可以返回,也有一个方法来确定是否内存分配成功地进行。这种方法是内建在语言内部来处理紧急情况的机制。一个预定好的函数指针 new-handler,它可以被设置为用户定制的对付new操作符失败的函数,这个函数可以进行任何的动作,包括设置错误标志、重新申请内存、退出程序或者抛出异常。你可以安心的使用系统内建的new-handler。最好的使构造函数发出出错信号的方法,就是抛出异常。在构造函数中抛出异常将清除错误之前创建的任何对象及分配的内存。
  如果构造函数失败而使用异常处理的话,那么,在另一个函数中进行初始化可能是一个更好的主意。这样,程序员就可以安全的构件对象并得到一个合理的指针。然后,初始化函数被调用。如果初始化失败的话,对象直接被清除。

3、构造函数不可以被声明为static
  C++中,每一个类的对象都拥有类数据成员的一份拷贝。但是,静态成员则没有这样而是所有的对象共享一个静态成员。静态函数是作用于类的操作,而不是作用在对象上。可以用类名和作用控制操作符来调用一个静态函数。这其中的一个例外就是构造函数,因为它违反了面向对象的概念。
  关于这些的一个相似的现象是静态对象,静态对象的初始化是在程序的一开始阶段就进行的(在main()函数之前)。下面的代码解释了这种情况。

  MyClass static_object(88, 91);

  void bar()
  {
  if (static_object.count( ) > 14) {
  ...
  }
  }

  在这个例子中,静态变量在一开始的时候就被初始化。通常这些对象由两部分构成。第一部分是数据段,静态变量被读取到全局的数据段中。第二部分是静态的初始化函数,在main()函数之前被调用。我们发现,一些编译器没有对初始化的可靠性进行检查。所以你得到的是未经初始化的对象。解决的方案是,写一个封装函数,将所有的静态对象的引用都置于这个函数的调用中,上面的例子应当这样改写。

  static MyClass* static_object = 0;

  MyClass*
  getStaticObject()
  {
  if (!static_object)
  static_object =
  new MyClass(87, 92);
  return static_object;
  }

  void bar()
  {
  if (getStaticObject()->count( ) > 15)
  {
  ...
  }
  }


4、构造函数不能成为虚函数
  虚构造函数意味着程序员在运行之前可以在不知道对象的准确类型的情况下创建对象。虚构造函数在C++中是不可能实现的。最通常遇到这种情况的地方是在对象上实现I/O的时候。即使足够的类的内部信息在文件中给出,也必须找到一种方法实例化相应的类。然而,有经验的C++程序员会有其他的办法来模拟虚构造函数。
  模拟虚函数需要在创建对象的时候指定调用的构造函数,标准的方法是调用虚的成员函数。很不幸,C++在语法上不支持虚构造函数。为了绕过这个限制,一些现成的方法可以在运行时刻确定构件的对象。这些等同于虚构造函数,但是这是C++中根本不存在的东西。
  第一个方法是用switch或者if-else选择语句来手动实现选择。在下面的例子中,选择是基于标准库的type_info构造,通过打开运行时刻类型信息支持。但是你也可以通过虚函数来实现RTTI

  class Base
  {
  public:
  virtual const char* get_type_id() const;
  staticBase* make_object
  (const char* type_name);
  };

  const char* Base::get_type_id() const
  {
  return typeid(*this).raw_name();
  }

  class Child1: public Base
  {
  };

  class Child2: public Base
  {
  };

  Base* Base::make_object(const char* type_name)
  {
  if (strcmp(type_name,
  typeid(Child1).raw_name()) == 0)
    return new Child1;
  else if (strcmp(type_name,typeid
    (Child2).raw_name()) == 0)
  return new Child2;
  else
  {
   throw exception
  ("unrecognized type name passed");
  return 0X00; // represent NULL
    }
  }
  
  这一实现是非常直接的,它需要程序员在main_object中保存一个所有类的表。这就破坏了基类的封装性,因为基类必须知道自己的子类。
  一个更面向对象的方法类解决虚构造函数叫做标本实例。它的基本思想是程序中生成一些全局的实例。这些实例只再虚构造函数的机制中存在:

  class Base
  {
  public:
    staticBase* make_object(const char* typename)
  {
   if (!exemplars.empty())
   {
    Base* end = *(exemplars.end());
    list<Base*>::iterator iter =
    exemplars.begin();
    while (*iter != end)
     {
      Base* e = *iter++;
      if (strcmp(typename,
        e->get_typename()) == 0)
        return e->clone();
     }
   }
    return 0X00 // Represent NULL;
  }
  virtual ~Base() { };
  virtual const char* get_typename() const
  {
   return typeid(*this).raw_name();
  }
  virtual Base* clone() const = 0;
  protected:
  static list<Base*> exemplars;
  };
  list<Base*> Base::exemplars;
  // T must be a concrete class
  // derived from Base, above
  template<class T>
  class exemplar: public T
  {
   public:
   exemplar()
   {
    exemplars.push_back(this);
   }
  ~exemplar()
   {
   exemplars.remove(this);
   }
  };
  class Child: public Base
  {
   public:
   ~Child()
    {
    }
   Base* clone() const
   {
    return new Child;
   }
  };
  exemplar<Child> Child_exemplar;

  在这种设计中,程序员要创建一个类的时候要做的是创建一个相应的exampler<T>类。注意到在这个例子中,标本是自己的标本类的实例。这提供了一种高校得实例化方法。

5、创建一个缺省构造函数
  当继承被使用的时候,却省构造函数就会被调用。更明确地说,当继承层次的最晚层的类被构造的时候,所有基类的构造函数都在派生基类之前被调用,举个例子来说,看下面的代码:

  #include<iostream.h>
  class Base
  {
   int x;
   public :
      Base() : x(0) { } // The NULL constructor
      Base(int a) : x(a) { }
  };
  class alpha : virtual public Base
   {
   int y;
   public :
   alpha(int a) : Base(a), y(2) { }
   };
  class beta : virtual public Base
   {
   int z;
   public :
   beta(int a) : Base(a), z(3) { }
   };
  class gamma : public alpha, public beta
   {
    int w;
    public :
       gamma ( int a, int b) : alpha(a), beta(b), w(4) { }
   };
  main()
  {.....
  }


  在这个例子中,我们没有在gamma的头文件中提供任何的初始化函数。编译器会为基类使用缺省的构造函数。但是因为你提供了一个构造函数,编译器就不会提供任何缺省构造函数。正如你看到的这段包含缺省构造函数的代码一样,如果删除其中的缺省构造函数,编译就无法通过。
  如果基类的构造函数中引入一些副效应的话,比如说打开文件或者申请内存,这样程序员就得确保中间基类没有初始化虚基类。也就是,只有虚基类的构造函数可以被调用。
  虚基类的却省构造函数完成一些不需要任何依赖于派生类的参数的初始化。你加入一个init()函数,然后再从虚基类的其他函数中调用它,或在其他类中的构造函数里调用(你的确保它只调用了一次)。


6、不能取得构造函数的地址
  C++中,不能把构造函数当作函数指针来进行传递,指向构造函数的的指针也不可以直接传递。允许这些就可以通过调用指针来创建对象。一种达到这种目的的方法是借助于一个创建并返回新对象的静态函数。指向这样的函数的指针用于新对象需要的地方。下面是一个例子:

  class A
  {
   public:
    A( ); // cannot take the address of this
       // constructor directly
   static A* createA();
     // This function creates a new A object
     // on the heap and returns a pointer to it.
     // A pointer to this function can be passed
     // in lieu of a pointer to the constructor.
  };

  这一方法设计简单,只需要将抽象类置入头文件即可。这给new留下了一个问题,因为准确的类型必须是可见的。上面的静态函数可以用来包装隐藏子类。

7、位拷贝在动态申请内存的类中不可行
  C++中,如果没有提供一个拷贝构造函数,编译器会自动生成一个。生成的这个拷贝构造函数对对象的实例进行位拷贝。这对没有指针成员的类来说没什么,但是,对用了动态申请的类就不是这样的了。为了澄清这一点,设想一个对象以值传递的方式传入一个函数,或者从函数中返回,对象是以为拷贝的方式复制。这种位拷贝对含有指向其他对象指针的类是没有作用的(见图2)。当一个含有指针的类以值传递的方式传入函数的时候,对象被复制,包括指针的地址,还有,新的对象的作用域是这个函数。在函数结束的时候,很不幸,析构函数要破坏这个对象。因此,对象的指针被删除了。这导致原来的对象的指针指向一块空的内存区域-一个错误。在函数返回的时候,也有类似的情况发生。



图2. The automatic copy constructor that makes a bitwise copy of the class.


  这个问题可以简单的通过在类中定义一个含有内存申请的拷贝构造函数来解决,这种靠叫做深拷贝,是在堆中分配内存给各个对象的。


8、编译器可以隐式指定强制构造函数
  因为编译器可以隐式选择强制构造函数,你就失去了调用函数的选择权。如果需要控制的话,不要声明只有一个参数的构造函数,取而代之,定义helper函数来负责转换,如下面的例子:

  #include <stdio.h>
  #include <stdlib.h>
  class Money
  {
   public:
      Money();
      // Define conversion functions that can only be
      // called explicitly.
      static Money Convert( char * ch )
      { return Money( ch ); }
      static Money Convert( double d )
      { return Money( d ); }
      void Print() { printf( "\n%f", _amount ); }
   private:
      Money( char *ch ) { _amount = atof( ch ); }
      Money( double d ) { _amount = d; }
      double _amount;

   };

  void main()
  {
   // Perform a conversion from type char *
   // to type Money.
   Money Account = Money::Convert( "57.29" );
   Account.Print();
   // Perform a conversion from type double to type
   // Money.
   Account = Money::Convert( 33.29 );
   Account.Print();
  }
  在上面的代码中,强制构造函数定义为private而不可以被用来做类型转换。然而,它可以被显式的调用。因为转换函数是静态的,他们可以不用引用任何一个对象来完成调用。


总结

  要澄清一点是,这里提到的都是我们所熟知的ANSI C++能够接受的。许多编译器都对ANSI C++进行了自己的语法修订。这些可能根据编译器的不同而不同。很明显,许多编译器不能很好的处理这几点。探索这几点的缘故是引起编译构造的注意,也是在C++标准化的过程中移除一些瑕疵。


参考文献:

1. Stroustrup, Bjarne. The C++ Programming Language, 3rd ed., Addison-Wesley, Reading, MA, 1997.
2. Ellis, Margaret and Bjarne Stroustrup. The Annotated C++ Reference Manual, Addison-Wesley, Reading,   MA, 1990.
3. Stroustrup, Bjarne. The Design and Evolution of C++, Addison-Wesley, Reading, MA, 1994.
4. Murry, Robert B. C++ Strategies and Tactics, Addison-Wesley, Reading, MA, 1993.
5. Farres-Casals, J. "Proving Correctness of Constructor Implementations," Mathematical Foundations of   Computer Science 1989 Proceedings.
6. Breymann, Ulrich. Designing Components with the C++ STL, Addison-Wesley, Reading, MA,1998.
7. Lippman, Stanley and Josee LaJoie. C++ Primer, 3rd ed., Addison-Wesley, Reading, MA, 1998.
8. Skelly, C. "Getting A Handle On The New-Handler," C++ Report, 4(2):1-18, February 1992.
9. Coggins, J. M. "Handling Failed Constructors Gracefully," C++ Report, 4(1):20-22, January 1992.
10. Sabatella, M. "Laser Evaluation of C++ Static Constructors," SIGPLAN Notices, 27(6):29-36 (June     1992).
11. Eckel, B. "Virtual Constructors," C++ Report, 4(4):13-16,May 1992.
12. Coplien, James O. Advanced C++: Programming Styles and Idioms, Addison-Wesley, Reading, MA, 1992.

07 Oktober

纯手工打造CPU,不得不佩服的东西

从MOP上看到的,把图片选过来....
 
外观:貌似是微波炉
 
 
工作中的Magic-1 Homebrew CPU,注意和它连接的那个本本,上面跑的什么?
 
 
内部样子,突然发现和我的spaces空间很配:
 
 
 
ALU/寄存器电路板....看到这个会想到什么?珍惜内存,远离动态分配和Java。
 
 
背面的走线:闲庭信步的美感
 
 
现在是逻辑单元的电路板:
 
 
完全手工走线的局部图:
 
 
作者的网站:http://www.homebrewcpu.com/

Magic-1是一个名叫Bill Buzbee的家伙手工打造的CPU,也是基于这个CPU制造的计算机的名字。“制作Magic-1的念头是在一次午餐中冒出来的”,Buzbee说。Buzbee是一位编译器作者,但他为自己不熟悉CPU的实际工作而感到郁闷,因此想到动手来亲自作一个CPU。Buzbee在大学时候没有学过任何电子类的课程,而且对于晶体管、电阻、电容等也只是一知半解。他的朋友Ken想到有一本老杂志曾经介绍过如何使用TTL集成电路来制作极其简单的CPU,并推荐他去看一看。一周后,Buzbee找到了这些文章,并全部读了一遍。然后在下一次午餐上,Buzbee对Ken说起决定自己打造一个CPU,Ken说:为什么不呢?于是,Bill Buzbee的Magic-1项目拉开了序幕——

2001年12月6日 Buzbee开始写项目日志,并为自己制定了一张艰难但还算乐观的日程表

2001年12月18日 完成错误处理和中断机制的基本设计
2001年12月29日 完成微代码的第一轮设计
2002年1月6日 完成了Magic-1模拟器,可以对调用/返回指令序列进行跟踪
2002年1月8日 模拟了Fibonacci函数,并丰富了软件接口约定
2002年1月13日 Magic-1汇编器(qas)成形
2002年1月18日 决定是选择大尾数法还是小尾数法表示整数的字节顺序,最终选择了大尾数法
2002年2月28日 在模拟器中完成了页面错误机制
2002年3月9日 决定使用普通电线来进行连线
2002年6月3日 对指令集架构进行了意义重大的改变
2002年6月4日 用C语言编写了Fabonacci程序并编译为Magic汇编程序
2002年6月22日 改用分立的数据和代码地址空间
2002年6月25日 设计用于多进程的上下文环境切换
2002年7月12日 完成对微代码的重写工作
2002年8月13日 放弃对rotate指令的支持
2002年9月11日 上了Gil Smith的一堂电子电路课程
2002年9月22日 从eBay上买了板材和外壳
2002年的其他日子 向Ken Sumrall请教如何使用寄存器,从他那里学到了Ohm规则
2003年3月30日 从Jhon Doran的D16/M中得到了灵感,完成了ALU/寄存器板的架构
2003年4月13日 完成控制板的架构
2003年4月14日 思考前面板的架构
2003年5月3日 第一轮架构设计完毕
2003年5月6日 将构建环境从Linux一直到Windows
2003年5月16日 构思新的Magic-1模拟器
2003年5月27日 在新的模拟器上成功运行了Fibonacci程序
2003年6月3日 完成了新的汇编器功能
2003年6月21日 Magic架构验证和测试用例达到了100%覆盖率
2003年6月23日 Alistair Roe通过email提出了Magic-1外壳的构想
2003年8月3日 将LCC(C编译器)一直到了Magic上
2003年8月10日 在模拟器上成功地实现了Fibonacci程序的C语言版本 (这一天是Buzbee的生日)
2003年8月27日 从David Conroy那里学到了信号完整性
2003年9月18日 决定使用普通的带皮电线进行连接(奇怪,前面已经决定一次了)
2004年1月3日 完成了全部的设计工作,开始制作
2004年1月18日 Magic-1有了第一次心跳
2004年1月26日 前面板完成
2004年2月9日 内存板完成
2004年2月20日 EPROM子板完成
2004年2月26日 设备板完成
2004年3月7日 微代码序列成功运转
2004年3月9日 执行了第一条指令
2004年3月19日 控制板完成
2004年4月8日 尝试发布前期的工作
2004年4月12日 ALU/寄存器板完成;同日被告知,发布尝试失败
2004年4月13日 Magic-1成功运行了Fibonacci程序!
2004年4月25日 Dave Conroy的测试会话发现了不真实的内存碎片
2004年5月3日 Magic-1能“说话”了
2004年5月8日 运行“Sieve of Erasthones”基准
2004年5月16日 完成了IDE接口,Alistair Roe完成了外壳设计
2004年7月23日 发布基本架构
2004年9月12日 用户模式程序可以工作
2004年9月15日 运行“Dhrystone”基准
2004年9月22日 使用copy-on-write实现了fork()
2004年10月23日 Magic-1的Dhrystone得分达到了384(0.25MIPS)
2004年10月31日 运行Colossal Cave Adventure
2005年4月9日 Alistair Roe设计的外壳到货
2005年5月13日 Magic-1的硬件设计完毕
这款“家酿”CPU可以支持完整的硬件地址转换、内存影射IO和DMA,并且支持多进程,主频“高达”3MHz;该CPU采用8位地址总线,每个进程拥有128K地址空间,其中包括32个2K的数据页和32个2K的代码页,这些地址影射到22位的物理地址空间中,如果算上外部设备的地址空间就是23位物理地址空间。

怎么样?够强的吧?这还不算什么,这个Buzbee还用这个CPU组装了一台微型计算机,名字就叫Magic-1,这台计算机包括两个串口和一块20M的1.3吋硬盘和另一块30M硬盘。最让人“乍舌”的事,这位朋友还将这台计算机做为一个Web服务器,同时支持Telnet会话(虽然只支持一个会话)。哦,还有,为了让这个系统能够跑起来,Buzbee还为它准备了一个C编译器!
 
不知道说什么了,完全震惊了...

 
 

仍会有玫瑰

仍会有玫瑰和杜鹃,在你死后,当你长眠。白色丁香仍会悄声絮语。

星点