Ordinary, But Passional

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  40 随笔 :: 0 文章 :: 41 评论 :: 0 Trackbacks

2009年5月22日 #

计算机

1、“计算机没什么用.他们只会告诉你答案.”
(巴勃罗·毕加索,画家)

2、“计算机就跟比基尼一样,省去了人们许多的胡思乱想.”
(萨姆·尤因,作家)

3、“他们拥有计算机,他们也还可能拥有其他的大规模杀伤性武器.”
(珍内特·雷诺,美国前女司法部长)

4、“跟计算机工作酷就酷在这里,它们不会生气,能记住所有东西,还有,它们不会喝光你的啤酒.”
(保罗·利里,吉他手)

5、“如果汽车能赶上计算机的发展周期的话,一辆今天的劳斯莱斯仅值100美元,每加仑要跑100万英里,每年还得爆炸一次,把里面的人杀个精光.”

(Robert X. Cringely,技术作家)

计算机智能

6、“计算机总是越来越智能的.科学家告诉我们说不久它们就能跟我们对话了.(这里的“它们”,我指的是“计算机”.我怀疑科学家永远都不能跟我们对话.)”
(Dave Barry,幽默作家)

7、“我最近注意到,在共同文化中,那种对计算机变得智能化并最终掌控世界的妄想恐惧症几乎彻底消失了.据我所知,这跟MS-DOS的发布基本是同步的.”
(Larry DeLuca)

8、“计算机会不会思考这个问题就像问潜水艇会不会游泳一样.”
(Edsger W. Dijkstra,图灵奖获得者)

9、“活了一百年却只能记住30M字节是荒谬的.你知道,这比一张压缩盘还要少.人类境况正在变得日趋退化.”
(Marvin Minsky,人工智能研究的奠基人)

信任

10、“这座城市的中央计算机告诉你的?R2D2,你不该相信一台陌生的计算机!”
(C3PO,星球大战中的翻译机器人)

11、“永远不要相信一台不能扔掉一扇窗户*的计算机”
(斯蒂夫·沃兹尼亚克,苹果联合创始人)
*译者:暗指微软的wINDOWS操作系统

硬件

12、“硬件:计算机系统中可被踢的部分.”
(Jeff Pesis)

软件

13、“今天大部分的软件都很像上百万块砖堆叠在一起组成的埃及金字塔,缺乏结构完整性,只能靠强力和成千上万的奴隶完成.”
(阿伦·凯,图灵奖获得者,面向对象创始人)

14、“我终于明白'向上兼容性'是怎么回事了.这是指我们得保留所有原有错误.”
(Dennie van Tassel)

操作系统

15、“有两样重要产品出自伯克利:LSD和BSD*.我们不相信这是个巧合.”

(Jeremy S. Anderson)

*译者:LSD是一种药力至强的迷幻剂,BSD-BSD(Berkeley Software Distribution,伯克利软件套件)是Unix的衍生系统

16、“2038年1月19日,凌晨3点14分07秒”
(UNIX中的世界末日*–1970年1月1号之后的2^32秒)

*译者:word跟world同音,UNIX用4个字节(WORD)表示时间,所以最多只能计时2^32秒

17、“每个操作系统都差不多… 我们都一样的烂.”
(微软的高级副总裁布莱恩·瓦伦蒂尼这样描述操作系统的安全状况,2003)

18、“微软有出了个新版本,Windows XP,据大家说是'有史以来最稳定的Windows', 对我而言, 这就好像是在说芦笋是'有史以来发音最清脆的蔬菜一样' “

(Dave Barry)

互联网

19、“互联网?那个东西还在吗?”
(Homer Simpson)

20、“网络就像是个母夜叉.我每转到一处都会看见小个的按钮命令我提交*.”
(Nytwind)

*译者注:Submit:提交,另一层意思是要求屈服


21、“想想看吧,已经有一百万只猴子坐在一百万台打字机旁,可Usenet就是比不上莎士比亚.”
(Blair Houghton)


软件产业

22、“计算机软件产业最为惊人的成就,是其持续不断地放弃硬件产业的惊人成果和稳定性.”

(Henry Petroski)


23、“真正的创新经常来自于那些贴近市场、但无力拥有市场的的小型初创公司.”

(Timm Martin)


24、“人们常说,伟大的科学学科就像是站在其它巨人肩膀上的巨人.人们也说过,软件产业正如站在其他侏儒脚上的侏儒.”
(Alan Cooper,交互设计之父)


25、“这无关比特、字节和协议,而关乎利润和损益.”
(郭士纳,IBM前CEO)


26、“我们是微软.反抗是徒劳的.你会被同化的.”
(保险杠贴纸)


软件演示



27、“不管演示在彩排的时候有多好,一旦在观众面前展示时,演示不出错的几率与观众人数成反比,与投入的金钱总额成正比.”
(Mark Gibbs)


软件专利

28、“专利大多数都是垃圾.浪费时间去阅读这些专利是愚蠢的.只有专利持有人才会这么干,还得强迫自己才会看.”

(Linus Torvalds,LINUX创始人)


复杂性

29、“控制复杂性是计算机编程的本质.”
(Brian Kernigan)


30、“复杂性杀死一切.它把程序员的生活给搞砸了,它令产品难以规划、创建和测试,带来了安全挑战,并导致最终用户和管理员沮丧不已.”
(Ray Ozzie)


31、“进行软件设计有两种方式.一种是让它尽量简单,让人看不出明显的不足.另一种是弄得尽量复杂,让人看不出明显的缺陷.”

(C.A.R. Hoare)


32、“好的软件的作用是让复杂的东西看起来简单.”
(Grady Booch,UML创始人之一)


易用性

33、“不管那些计算机书籍如何宣称,只需记住,你并非'傀儡'.真正的傀儡是那些无法设计出易于使用的硬件和软件的那些人,尽管他们是技术专家,因为这是普通消费者赖以生活的东西.”

(Walter Mossberg,科技专栏记者)


34、“软件供应商在努力尝试让他们的软件更'易于操作'… 迄今为止,他们最好的办法就是翻出所有的老手册,然后在封面盖上'易于操作'这几个字.”

(比尔·盖茨)

35、“有个老套的故事说有人希望他的计算机能像他的电话机一样好用.他的愿望实现了,因为我已经不知道该如何使用自己的电话了.”
(Bjarne Stroustrup,C++之父)


用户

36、“任何一个傻瓜都会用电脑.很多都会.”
(Ted Nelson)


37、“只有两个行业把客户称为'用户'*.”

(Edward Tufte,信息设计大师)
*译者注:一个是计算机设计,另一个是毒品交易,computer design and drug dealing

程序员

38、“程序员在跟宇宙赛跑,他们在努力开发出更大更好的傻瓜程序,而宇宙则努力培养出更大更好的白痴.到目前为止,宇宙领先.”
(Rich Cook)

39、“你们当中很多人都知道程序员的美德.当然啦,有三种:那就是懒惰、急躁以及傲慢.”
(Larry Wall,Perl发明者)


40、“程序员的问题是你无法预料他在做什么,直到为时已晚.”
(Seymour Cray,超级计算机之父)



41、“那就是这些自认为痛恨计算机的人的真实面目.他们实际上真正痛恨的是糟糕的程序员.”
(拉瑞·尼文,科幻作家)


42、“很长时间以来我一直困惑不已,为什么一些又贵又先进的东西会一点用都没有.直到我突然想起,计算机不就是一台愚蠢之至却拥有难以置信的做聪明事能力的机器嘛,而程序员不就是聪明绝顶却拥有难以置信的干蠢事的能力的人嘛.一句话,他们简直就是天生绝配.”
(比尔·布莱森,旅游文学作家)


43、“不像学学涂涂画画也能让某人成为专家级画家,计算机科学教育不会让任何人成为一名编程大师.”

(埃里克·雷蒙,开源运动领袖)



44、“一个程序员是经历以下事情后仍能证明自己是严格的专家的人:他可以历经数不清的捶打,可取材于无关紧要的文档,用上面的争议数据作出模糊假设,并以此计算出测微精度的无数片面理解的答案,并由一个不可靠、脑袋充满质疑、公开宣称要让一个倒霉透顶、没有指望、毫无防备,要求第一时间获得信息的部门狼狈不堪、令人生厌的人使用一台准确度有问题的仪器去实施.”

(IEEE网格新闻杂志)



45、“运气好的黑客能用几个月的时间 - 生产出一个小规模的开发团体(比如说,7-8人)历尽艰辛一起工作了一年多才能做出来的东西.IBM经常报告说某些程序员的生产力要比其它工人高百倍,甚至更多.”

(Peter Seebach,黑客)


46、“最好的程序员跟好的程序员相比可不止好那么一点点.这种好不是一个数量级的,取决于标准怎么定:概念创造性、速度、设计的独创性或者解决问题的能力.”
(兰德尔·E·斯特劳斯,科技作家)


47、“伟大的车工值得给他几倍于普通车工的薪水,但一个伟大的软件代码作家,其价值则要等同于一个普通的软件写手的价格的1万倍.”
(比尔·盖茨)

编程

48、“就算它工作不正常也别担心.如果一切正常,你早该失业了.”
(Mosher的软件工程定律)


49、“靠代码行数来衡量开发进程就好比用重量来衡量飞机制造的进度.”
(比尔·盖茨)

50、“写代码的社会地位比盗墓的高,比管理的低.”
(杰拉尔·德温伯格,软件与系统思想家)



51、“首先学习计算机科学及理论.接着形成自己编程的风格.然后把这一切都忘掉,尽管改程序就是了.”
(George Carrette,杰出软件工程师,开源推广者)



52、“先解决问题再写代码.”
(John Johnson)


53、“乐观主义是编程行业的职业病;用户反馈则是治疗方法.”
(Kent Beck)


54、“迭代者为人,递归者为神.”
(L. Peter Deutsch)


55、“布尔值最好的一点是,就算你错了,也顶多错了一位而已.”
(无名氏)


56、“数组的下标是从0开始好还是从1开始好呢?我的0.5的折衷方案,以我之见,没有经过适当考虑就被否决掉了.”

(Stan Kelly-Bootle)


编程语言

57、“只有两种编程语言:一种是天天挨骂的,另一种是没人用的.”
(Bjarne Stroustrup,C++之父)


58、“PHP是不合格的业余爱好者创建的,他们犯做了个小恶;Perl是娴熟而堕落的专家创建的,他们犯了阴险狡诈的大恶.”

(Jon Ribbens)


59、“COBOL的使用摧残大脑;其教育应被视为刑事犯罪.”
(E.W. Dijkstra)


60、“把良好的编程风格教给那些之前曾经接触过BASIC的学生几乎是不可能的.作为可能的程序员,他们已精神残废,无重塑的可能了.”

(E. W. Dijkstra)


61、“我想微软之所以把它叫做.Net,是因为这样它就不会在Unix的目录里显示出来了.”
(Oktal)


62、“There is no programming language–no matter how structured–that will prevent programmers from making bad programs.”
(Larry Flon)

63、“计算机语言设计犹如在公园里漫步.我是说侏罗纪公园.”
(Larry Wall)


C/C++

64、“搞了50年的编程语言的研究,我们难道就以C++告终啦?”
(Richard A. O'Keefe)


65、“写C或者C++就像是在用一把卸掉所有安全防护装置的链锯.”
(Bob Gray)


66、“在C++里你想搬起石头砸自己的脚更为困难了,不过一旦你真的做了,整条腿都要报销.”
(Bjarne Stroustrup)


67、“C++ : 友人可造访你的私有成员之地也.”
(Gavin Russell Baker)

译者:Friends:C++的友元,是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend.友元不是成员函数,但是它可以访问类中的私有成员.友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员.


68、“罗马帝国灭亡的其中一个主要原因是他们没有0 - 这样他们就没法给自己的C程序指明成功退出的路径了.”
(Robert Firth)


Java

69、“Java从许多方面来说就是C++–.”
(Michael Feldman)


70、“说Java好就好在运行于多个操作系统之上,就好像说肛交好就好在不管男女都行.”

(Alanna)


71、“好吧,Java也许是编程语言的好榜样.但Java应用则是应用程序的坏榜样.”
(pixadel)


72、“要是Java真的有垃圾回收的话,大部分程序在执行的时候就会把自己干掉了.”
(Robert Sewell)


开源

73、“软件就像性事:免费/自由更好.”
(Linus Torvalds)


74、“唯一对免费软件感到害怕的人,是自己的产品还要不值钱的人.”
(David Emery)


代码

75、“好代码本身就是最好的文档.”
(Steve McConnell)


76、“你自己的代码如果超过6个月不看,再看的时候也一样像是别人写的.”
(伊格尔森定律)


77、“前面90%的代码要占用开发时间的前90%.剩下的10%的代码要占用开发时间的另一90%.”

(Tom Cargill)


软件开发

78、“好的程序员会用脑,但是好的向导救我们于样样都要想到.”
(Francis Glassborow)


79、“在软件里面,我们鲜有有意义的需求.就算有,衡量成功的唯一尺度也取决于我们的解决方案是否解决了客户对问题是什么的观念的转变.”
(Jeff Atwood)

80、“想想我们计算机程序的糟糕现状吧,很显然软件开发仍是黑箱艺术,还不能称之为工程学科.”
(Bill Clinton,前美国总统)


81、“没有伟大的团队就没有伟大的软件,可大部分的软件团队举止就像是支离破碎的家庭.”
(吉姆·麦卡锡,微软VC++总监)


调试

82、“一旦我们开始编程,就会惊讶地发现让程序正常没想象中那么简单.调试不可避免.那一刻我认记忆犹新,当时我就意识到,从今往后我生活的大部分时间都要花在寻找自己程序的错误上面了.”

(莫里斯·威尔克斯 调试探索, 1949)


83、“调试难度本来就是写代码的两倍.因此,如果你写代码的时候聪明用尽,根据定义,你就没有能耐去调试它了.”
(Brian Kernighan)


84、“如果调试是除虫的过程,那么编程就一定是把臭虫放进来的过程.”
(Edsger W. Dijkstra)


质量

85、“我才不管它能不能在你的机器上运行呢!我们又没装到你的机器上!”

(Vidiu Platon,罗马尼亚的微软最佳学生合作伙伴MSP)



86、“编程就像性一样:一时犯错,终生维护.”
(Michael Sinz)


87、“有两种写出无错程序的办法;只有第三种有用.”
(Alan J. Perlis)


88、“软件质量与指针算法不可兼得.”
(Bertrand Meyer)


89、“如果麦当劳像软件公司那样运作的话,每一百个巨无霸就会有一个令你食物中毒,而他们的回应是,'真对不起,这是一张额外附送两个的赠券.' “
(Mark Minasi)


90、“永远要这样写代码,好像最终维护你代码的人是个狂暴的、知道你住在哪里的精神病患者.”

(Martin Golding)


91、“是人都会犯错,不过要想把事情彻底搞砸还得请电脑出马.”
(Paul Ehrlich)


92、“计算机比人类历史上的任何发明都更快速地导致你犯更多的错误–可能除了手枪和龙舌兰酒是例外.”

(Mitch Radcliffe)


预测

93、“能发明的东西都发明出来了.”
(查尔斯·杜埃尔, 美国专利局局长,1899年)


94、“我认为全球市场约需5台计算机.”
(托马斯·沃森, IBM董事长, 约1948年)



95、“看上去我们已经到达了利用计算机技术可能获得的极限了,尽管下这样的结论得小心,因为不出五年这听起来就会相当愚蠢.”

(约翰·冯·诺伊曼,约1949年)


96、“但这又有什么好处呢?”
(IBM先进计算机系统部的工程师对微芯片的评论, 1968年)


97、“我们没有理由让每一个人在家都拥有一台电脑.”
(肯·奥尔森,数据设备公司(DEC)总裁,1977年)

98、“640K对每一个人来说都已足够.”
(比尔·盖茨,1981年)



99、“Windows NT的RAM寻址空间可达2G,这比任何应用程序所需都要多.”

(微软, 谈及Windows NT的开发时所言, 1992年)

100、“我们永远也无法真正成为无纸化社会,直到掌上电脑一族发布擦我1.0*(WipeMe 1.0)为止.”

(安迪•皮尔逊,商界领袖)

*译者注:意思是说难道你大便不用纸吗?


101、“长此以往,除了按键的手指外,人类的肢体将全部退化.”
(弗兰克•劳埃德•赖特,建筑师)

posted @ 2009-05-22 12:35 彭小虎(Tigerkin) 阅读(29) | 评论 (0)编辑 收藏

2008年11月25日 #

  1. 准备一张图片,格式为BMP,长宽为64像素、128像素或256像素。
  2. 声明一个变量来存放纹理。
    GLuint texture[1];
  3. 用LoadBMP()载入图片,返回一个指向AUX_RGBImageRec的指针。
    AUX_RGBImageRec* texture_image[1];
    memset(texture_image, 0, sizeof(void*));
    texture_image[0] = LoadBMP(“winxp.bmp”);
  4. 创建一个纹理,并指定纹理的属性。
    glGenTextures(1, &texture[0]);
    glBindTextrue(GL_TEXTURE_2D, texture[0]);
  5. 生成纹理。
    glTexImage2D(GL_TEXTURE_2D, 0, 3, texture_image[0]->sizeX, texture_image[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_image[0]->data;
  6. 设置当图片大于(小于)纹理大小时的显示方式。
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  7. 使纹理有效。
    glEnable(GL_TEXTURE_2D);
  8. 在画的过程中,如果有多个纹理,需要使用glBindTexture(GL_TEXTURE_2D, texture[0])选择纹理。
posted @ 2008-11-25 01:35 彭小虎(Tigerkin) 阅读(97) | 评论 (0)编辑 收藏

2008年11月17日 #

写了个俄罗斯方块,逻辑算法部分中规中矩,棋盘主要采用二维数组的数据结构,而每种方块样式都是Block类的一个对象,方便扩充;界面部分采用了DialogBox,用GDI画,同时还使用双缓冲技术防止画面闪烁。考虑到可以在RC文件里设计程序界面,所以采用了Dialogbox作为主界面,于是麻烦便来了:DialogBox无法接受WM_KEYDOWN中的VK_UP,VK_DOWN等,也就是说上下左右按键没法用。。试了几种办法,都不行,干脆换成了home,end,page up,page down键。玩的时候很不方便~等我再查查资料再改吧,先把这个有残缺的1.0版本发上来。

程序截图:tetris

下载地址:可执行文件源代码

posted @ 2008-11-17 00:59 彭小虎(Tigerkin) 阅读(119) | 评论 (4)编辑 收藏

2008年10月28日 #

很久没更新了。。发一个自己写的String类,可以自己指定使用ANSI还是UNICODE。这里下载

class String
{
private:
	wchar_t* wdata;
	char* data;
public:
	CharSet cs;
	String(CharSet _cs = USE_UNICODE, int size = 0);	// 默认使用UNICODE,不分配内存(size为0)
	String(const String& str, CharSet _cs = USE_ORIG);	// 必须是引用
	String(const char* str, CharSet _cs = USE_UNICODE);
	String(const wchar_t* str, CharSet _cs = USE_UNICODE);
	~String();

	// 可以从外部直接获得字符串在内存中的地址(小心使用~~)
	char* AnsiStr();		
	wchar_t* UnicodeStr();

	String& operator =(const String& str);
	String& operator =(const char* str);
	String& operator =(const wchar_t* str);

	String operator +(const String& str);
	String operator +(const char* str);
	String operator +(const wchar_t* str);

	String& operator +=(const String& str);
	String& operator +=(const char* str);
	String& operator +=(const wchar_t* str);
	
	int Find(const String& str);
	int Find(const char* str);
	int Find(const wchar_t* str);

	String SubStr(int start, int length);

	void Swap(String& str);

	int Length() const;
	void Clear();
};
posted @ 2008-10-28 20:36 彭小虎(Tigerkin) 阅读(91) | 评论 (0)编辑 收藏

2008年8月16日 #

我要在MSDN里搜Windows API DrawText函数,如图:

Google: 第一条就是。

Live Search:  找了半天没找到

posted @ 2008-08-16 12:23 彭小虎(Tigerkin) 阅读(86) | 评论 (1)编辑 收藏

以往写Windows程序,用的较多的是Delphi的VCL,MFC用的很少,总觉得不习惯,相比MFC我倒宁愿用清新简单的Windows API。呵呵。于是乎,我萌生了一个想法,自己来封装Windows API。开始动手。。

首先我找了一个比较简单的Window API程序,试着把他转换成面向对象的形式。程序尽管简单,但刚上来一个棘手的问题就出现了。。消息机制的封装。

我们都知道,Windows中比如点击按钮,移动窗口等等的交互操作都是由消息机制来完成的。每做一个动作,例如点击一个按钮,Windows便会产生一个相应的消息,在这里就是BN_CLICKED,假设点击按钮后会弹出一个窗口,里面显示若干文字,而这些点击按钮后产生的效果就需要由我们程序员来编写。体现在Windows API中便是“消息处理函数”,如下:

 

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     
switch (message)
     {
     
case BN_CLICKED:

          
//相关代码
          return 0 ;

     
case WM_DESTROY:
          PostQuitMessage (
0) ;
          
return 0 ;
     }
     
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

 

每次都要写这么多case的确是挺麻烦的,于是我想用面向对象的方法解决他。

 

class MessageMap
{
public:
     
int count;  // 消息映射的数目
      Message* message[10];  // 可以存放10对消息映射
      template <typename T>
     
void Add(MessageType 消息名称, T* 对应的处理函数);  // 增加一对消息映射
};

template 
<typename T>
class Message
{
public:
     MessageType 消息名称;
     T
* 对应的处理函数;
     
void Run()
     {
          对应的处理函数();
     }
};

enum MessageType{}

 

这样做其实是有问题的,请看这一段:

 

class MessageMap
{
public:
     
      Message
* message[10];  // 由于Message是模板类,这里应该提供模板参数。这样就失去了模板的作用。
                                
// 我们使用模板就是为了能让他存储不同的函数指针。
      
};

 

想一想,如何用一个统一的接口来调用不同的函数?对了,那就是多态。

我们可以增加一个抽象的接口类来提供调用接口,而具体实现的类则由他派生。

 

class MessageInterface
{
public:
    MessageType type;
    
virtual ~MessageInterface() {}
    
virtual void Run() = 0;
}
;

template 
<typename T>
class Message : public MessageInterface
{
public:
    T
* classPtr;
    
void (T::* funcPtr)();
    Message(MessageType _type, T
* _classPtr, void (T::* _funcPtr)()) : classPtr(_classPtr), funcPtr(_funcPtr)
    
{
        type 
= _type;
    }

    
virtual void Run()
    
{
        
if (classPtr)
        
{
            (classPtr
->*funcPtr)();        // 注意调用函数指针时括号的用法
        }

    }
    
}
;

class MessageMap
{
public:
    
int count;
    MessageMap()
    
{
        count 
= 0;
        Add(DESTROY, 
this&MessageMap::OnDestroy); 
    }

    MessageInterface
* message[10];
    
void OnDestroy()
    
{
        PostQuitMessage(
0);
    }

    template 
<typename T>
    
void Add(MessageType type, T* classPtr, void (T::* funcPtr)())
    
{
        message[count
++= new Message<T>(type, classPtr, funcPtr);
    }

}
;

 

问题解决了!哈哈,测试成功!

具体的代码在这里,结构什么的还很不完善,仅仅是处理了消息机制而已,当作演示吧。

 

posted @ 2008-08-16 11:45 彭小虎(Tigerkin) 阅读(1450) | 评论 (18)编辑 收藏

2008年8月7日 #

今天接到leader布置的一个任务,从TextBox继承一个新的控件并为其增加一些功能,其中一个功能如下:

Add a property: FormatString, when the text box lost focus, the content will be replace with string.Format(FormatString, actualContent),我在做第二个:“当textbox失去焦点时自动格式化文本”的地方遇到了问题。。。

简单起见,简化成“当textbox失去焦点时改变文本内容”。

一种方法是:

重写OnLeave()方法,如下:

protected override void OnLeave(EventArgs e)
{
        
base.OnLeave(e);
        
this.Text = "Override OnLeave";
}

另一种是给Leave事件增加一个订阅者:

private void NewReceiver(object sender, EventArgs e)
{
        
this.text = "NewReceiver";
        Invalidate();
}

//constructor
public MyTextBox()
{
        
this.Leave += new EventHandler(NewReceiver);
}

经测试,均可运行。

现在,把两段代码和在一起,并注释掉第一种方法:

protected override void OnLeave(EventArgs e)
{
    
base.OnLeave(e);
    
//this.Text = "Override OnLeave";
}

private void NewReceiver(object sender, EventArgs e)
{
    
this.text = "NewReceiver";
    Invalidate();
}

//constuctor
public MyTextBox()
{
    
this.Leave += new EventHandler(NewReceiver);
}

运行程序,测试,显示NewReceiver。

接下来再把base.OnLeave(e)注释掉:

protected override void OnLeave(EventArgs e)
{
    
//base.OnLeave(e);
    
//this.Text = "Override OnLeave";
}

private void NewReceiver(object sender, EventArgs e)
{
    
this.text = "NewReceiver";
    Invalidate();
}

//constuctor
public MyTextBox()
{
    
this.Leave += new EventHandler(NewReceiver);
}

运行,发现文本框失去焦点后不会改变内容,仍未空。由此,第二种方法失效了。为何?我们来看一下base.OnLeave()的内容:

protected virtual void OnLeave(EventArgs e)
{
    EventHandler handler 
= (EventHandler) base.Events[EventLeave];
    
if (handler != null)
    {
        handler(
this, e);
    }
}

原来,注释掉这段以后,handler(this, e)无法得到执行,也就没法激发事件,文本框内容当然也就没法改变了。

 

由此,我猜测,C#的事件触发过程大致是这样的:

文本框失去焦点 --> 触发Leave事件 --> 调用OnLeave()函数(这里是因为什么机制调用的?) --> 调用base.OnLeave() --> 再次触发Leave事件 --> 调用NewReceiver() --> 返回,执行this.text = "Override OnLeave"。

红色字,大家谁知道的,帮我解个惑吧~~

posted @ 2008-08-07 19:22 彭小虎(Tigerkin) 阅读(47) | 评论 (0)编辑 收藏

2008年8月2日 #

很多东西,不是你不会做,而是你不敢去做。久而久之,庸庸碌碌。。

要这么想:有什么东西是天生就会的呢!

posted @ 2008-08-02 17:35 彭小虎(Tigerkin) 阅读(15) | 评论 (0)编辑 收藏

2008年7月30日 #

一,公钥私钥
1,公钥和私钥成对出现
2,公开的密钥叫公钥,只有自己知道的叫私钥
3,用公钥加密的数据只有对应的私钥可以解密
4,用私钥加密的数据只有对应的公钥可以解密
5,如果可以用公钥解密,则必然是对应的私钥加的密
6,如果可以用私钥解密,则必然是对应的公钥加的密
明白了?

假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们,然后我告诉大家,1是我的公钥。

我有一个文件,不能让别人看,我就用1加密了。别人找到了这个文件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以用数字2,就是我的私钥,来解密。这样我就可以保护数据了。

我的好朋友x用我的公钥1加密了字符a,加密后成了b,放在网上。别人偷到了这个文件,但是别人解不开,因为别人不知道2就是我的私钥,只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。

现在我们知道用公钥加密,然后用私钥来解密,就可以解决安全传输的问题了。如果我用私钥加密一段数据(当然只有我可以用私钥加密,因为只有我知道2是我的私钥),结果所有的人都看到我的内容了,因为他们都知道我的公钥是1,那么这种加密有什么用处呢?

但是我的好朋友x说有人冒充我给他发信。怎么办呢?我把我要发的信,内容是c,用我的私钥2,加密,加密后的内容是d,发给x,再告诉他解密看是不是c。他用我的公钥1解密,发现果然是c。这个时候,他会想到,能够用我的公钥解密的数据,必然是用我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。这样我们就能确认发送方身份了。这个过程叫做数字签名。当然具体的过程要稍微复杂一些。用私钥来加密数据,用途就是数字签名。

好,我们复习一下:
1,公钥私钥成对出现
2,私钥只有我知道
3,大家可以用我的公钥给我发加密的信了
4,大家用我的公钥解密信的内容,看看能不能解开,能解开,说明是经过我的私钥加密了,就可以确认确实是我发的了。

总结一下结论:
1,用公钥加密数据,用私钥来解密数据
2,用私钥加密数据(数字签名),用公钥来验证数字签名。

在实际的使用中,公钥不会单独出现,总是以数字证书的方式出现,这样是为了公钥的安全性和有效性。

二,SSL
我和我得好朋友x,要进行安全的通信。这种通信可以是QQ聊天,很频繁的。用我的公钥加密数据就不行了,因为:
1,我的好朋友x没有公私钥对,我怎么给他发加密的消息啊? (注:实际情况中,可以双方都有公私钥对)
2,用公私钥加密运算很费时间,很慢,影响QQ效果。

好了,好朋友x,找了一个数字3,用我的公钥1,加密后发给我,说,我们以后就用这个数字来加密信息吧。我解开后,得到了数字3。这样,只有我们两个人知道这个秘密的数字3,别的人都不知道,因为他们既不知x挑了一个什么数字,加密后的内容他们也无法解开,我们把这个秘密的数字叫做会话密钥。

然后,我们选择一种对称密钥算法,比如DES,(对称算法是说,加密过程和解密过程是对称的,用一个密钥加密,可以用同一个密钥解密。使用公私钥的算法是非对称加密算法),来加密我们之间的通信内容。别人因为不知道3是我们的会话密钥,因而无法解密。

好,复习一下:
1,SSL实现安全的通信
2,通信双方使用一方或者双方的公钥来传递和约定会话密钥 (这个过程叫做握手)
3,双方使用会话密钥,来加密双方的通信内容

上面说的是原理。大家可能觉得比较复杂了,实际使用中,比这还要复杂。不过庆幸的是,好心的先行者们在操作系统或者相关的软件中实现了这层(Layer),并且起了一个难听的名字叫做SSL,(Secure Socket Layer)。

posted @ 2008-07-30 11:16 彭小虎(Tigerkin) 阅读(65) | 评论 (0)编辑 收藏

2008年3月16日 #

 

class String
{
public:
    String( 
const char *str = "" );
    
~String();
    String( 
const String &another )
    
{
        
const char *str = another.m_data;  // 可以正常访问
        /*省略*/
private:
    
char *m_data;
}
;

c++里,类的访问权限是class level,不是object level的。
访问权限只在编译时对编译器有效,在运行时,不存在访问权限这道栅栏。  

以下转自网上:

/**  
    *   请大家看看下面这段程序,它是能够正常编译连接运行的。但是为什么  
    *   assign成员函数没有错呢?谁能告诉我c++中关于这种情况的内幕?谢谢!  
    */  
   
  #include   <stdio.h>  
   
  class   Test    
  {  
  private:  
          int   a;  
  public:  
          Test(int);  
          void   assign(Test   const*   source);  
  };    
   
  void   Test::assign(Test   *source)  
  {  
          a   =   source->a;  
  }  
   
  int   main()  
  {  
          Test   t1(1),   t2(2);  
          t2.assign(&t1);  
  }  
   
  1:   关于ACCESS-CONTROL的定义  
   
      <<C++98   std/chapter   11>>:  
      1   A   member   of   a   class   can   be  
   
      --private;   that   is,   its   name   can   be   used     only     by      
          member     functions,   static     data     members,     and      
          friends     of     the     class     in   which   it   is   declared.  
   
      --protected;   that   is,   its   name   can   be   used   only   by  
          member     functions,   static     data     members,     and    
          friends     of     the     class     in   which   it   is   declared    
          and   by   member   functions,   static   data   members,      
          and     friends   of   classes   derived   from   this   class.  
   
      --public;     that     is,     its     name     can     be     used    
          anywhere   without   access   restriction.  
   
  2:   一些相关的note:  
        1)   name  
        ACCESS-CONTROL   只应用到name(simple   identifier).  
        按照上面的定义,ACCESS-CONTROL针对且只针对    
        member   of   class.        
        即使是涉及到模板,也只是关心name,    
        而不关心template-argument  
         
        2)   unnamed   object  
        无名对象不考虑access-control:  
        如下:  
        struct   A  
        {  
        private:  
              struct   B    
              {  
                  int   i;  
              };  
              B   m_b;  
        public:  
              B&   f()   {   return   m_b;   }            
        };  
        int   main()  
        {  
            A   a;  
            f()->i;   //   only   names   are   f,   i,    
                            //   f   and   i   is   public,    
                            //   so   it's   legal   even    
                            //   if   B   in   private   A   member  
        }        
        3)   关于protected   member   name有一个例外情况,  
              参见(4:)中例子的new   note  
   
  3:   让人迷惑的代码段的注记  
   
        void   Test::assign(Test   *source)  
        {  
          a   =   source->a;  
          /**  
            1)   这里出现的name是  
                  void,   Test,   assign,   source,   a  
            2)   void,   Test,   source,    
                不是class   member,    
                不做access-control考虑  
            3)   assign是成员函数名,    
                  但我们只是定义它,  
                  不在这里使用,  
                  也不做access-control考虑  
   
            4)a是private   Test   member,    
                  可以在A的成员函数中使用,  
                  现在刚好是在Test的  
                  assign成员函数体内。  
                   
            5)   but   what   about   "source->a":  
                  OK,   a   in   "source->a"   means    
                  a   is   a   member   name   of   source's   class   Test  
                  and   used   in   Test   member   function,    
                  everything   is   fine!!!  
                  (still   confusing,   see   following   example   ...)  
            */  
        }  
   
  4:   更加清楚的例子(我的)注记  
       
        struct   Base  
        {  
        protected:  
            int   m_protected;  
        };  
   
        struct   Son2   :   Base   {};  
   
        struct   Son1   :   Base  
        {  
   
            void   foo(Son1&   s)  
            {  
                s.m_protected;           /**  
                                                  new   note:  
                                                  same   as   3/5)  
                                                  */  
            }  
   
            void   foo(Base&   b)  
            {  
                b.m_protected;    /**  
                                          new   note:  
                                          m_protected   in   "b.m_protected"   means:  
                                              m_protected   is   Base(b's   type)   class    
                                              member,   not   Son1   class   member  
                                          which   means:  
                                              Base's   protected   member   is   used  
                                              in   Son1's   member   function    
                                          By   definition,   it's   legal,   but  
                                          因为C++标准规定一个关于  
                                          proected   member的例外情况,  
                                              When   a   member   function   of   a      
                                              derived     class   references      
                                              a     protected   nonstatic   member  
                                              of   a   base   class,   an   access   check    
                                              applies   in   addition     to     those    
                                              described   earlier   in   this   clause:  
                                                Except   when   forming   a   pointer   to  
                                                member,the   access   must   be   through    
                                                          a   pointer   to,  
                                                          reference   to,      
                                                          <---我们的情况  
                                                          or   object              
                                                          <---下一个成员函数的情况  
                                                      of   the   derived   class   itself    
                                              (or   any   class   derived   from   that   class).  
                                          因为儿子不能管老子,所以结论是  
                                          illegal    
                                          */  
   
            }  
            void   foo(Base   b)  
            {  
                b.m_protected;  /**  
                                        new   note:  
                                        illegal   :   儿子不能管老子  
                                        原因同   void   foo(Base&   c)的分析。  
                                        */  
            }    
      };  

posted @ 2008-03-16 19:29 彭小虎(Tigerkin) 阅读(34) | 评论 (0)编辑 收藏

仅列出标题  下一页