xhliu 的个人资料青蛙王子的工作空间照片日志列表 工具 帮助

日志


12月20日

设计模式: singleton

singleton模式是5种创建型模式中最简单的一个了,一句话:  整个程序中只有一个实例. singleton还是有很多用处的,比如打星际争霸,一场游戏中只能有一个地图, 最多8个玩家. 这里的地图就是一个singleton,而玩家就应该是一个扩展的singleton。
 
其实,直接声明一个global static变量,也能保证全局只有一个实例,可是他的问题在于,自己声明了一个变量,然后过了两年,别人看到了自己的代码,要重新用它,已经忘记了原来的用途,这时候,10个8个变量都有可能了。
 
singleton模式的意义在于在代码上保证了他不能声明多个变量,如果声明了就会编译错误。这个市符合effective c++中的一个原则的:如果你在设计上就不考虑它,那就应该名令禁止他。
 
然而,singleton还是有很多问题的,比如在多线程的时候,在dll中,只有考虑了这些问题的singleton才是真正的singleton。

学习设计模式 第一天,第二天

根据老大的推荐,决定看设计模式这本书,看了之后发现果然是一本好书.
 
这两天看得主要是创造型模式,主要有5类: Singleton, Factory Method, Prototype, Abstract Factory, Builder
 
总的来说,这5种模式主要是为了创建变量的.举一个例子,我们要写一个游戏星际争霸. 里面有很多的东西,比如小兵,坦克,飞机,碉堡等等. 这些对象的创建,摧毁都应该有一个系统的方法. 如果到处new来delete去的,系统做大了就没法工作了.
 
总而言之, 创建型模式就是为了把创建变量这个神圣的事情 从手工作坊(单独的new) 提升到 工业化(5种模式) 的高度.
 
以上个人理解.
8月21日

strong code

经过这么长时间的training,发现把自己的代码编程solid code是非常必要的。而成为solid code的第一步,就是改变以前的种种毛病,真正让自己的代码毫无问题。写出solid code有几步是必要的。1)进行代码design。2)进行变量、函数名字设计。3)进行注释的编写。4)进行单元测试。5)进行buddy build。6)进行代码review。7)形成上述工作的适合自己的checklist。现在要一步一步的学习。
7月25日

学习c#第4天

31:c#中的windows编程中的控件
答:c#中的空间都是从Control类中派生出来,Control类中主要有消息路由等信息。而控件在窗口中布局的时候,通过代码控制和通过ToolsBox控制是完全等同的,只需要最后用this.Controls.Add()添加相应的控件就可以了。
 
32:c#中的自定义控件
答:c#中的自定义控件有3种。
     1) 从原来控件类派生出来的控件,如Button, TextBox等,他们可以直接使用,也可以改变了某些属性后使用,很方便。
     2) 直接从Control类派生出来的控件,通过填写一些必要的接口以后,就可以使用,使用方法不需要经过ToolsBox来拖动,直接添加就可以了。
     3) 多个控件的组合,从UserControl类派生出来的类。他生成一个控件集合:控件库。放在一个dll文件里面。在使用的时候,只需要在ToolBox中导入这个dll,控件就会出现在ToolsBox上,用户就可以使用了,方法和一般的控件差不多。
 
33:编写测试程序:俄罗斯方块1.0版,定义如下:

Smart blocks设计思想:

设计一个俄罗斯方块程序,用来练习c#。

 

1.0版,应该包含以下功能:

1)        标准的俄罗斯方块程序

2)        游戏的开始、结束、记分、时间、庆祝等功能。

 

以后版,应该包含以下功能:

1)        用户管理,积分榜

2)        变异方块、对战

3)        网络对战

4)        基于web程序等

5)        难度选择、针对层数等的扩展

 

1.0版包含的模块:

1)        包含一个方块的容器:BlocksContainer,具有以下功能

a)         可以选择背景,可以配置

b)        设置方块数目宽、高(默认10宽,25高)

c)        可以设置心跳(正常心跳、快速心跳)

d)        设置每个方块的宽高(宽=高,根据分辨率设置最好的)

e)         移动方块及方块组:左、又、下

f)         对方块组的变形

g)        删除方块组

h)        重置方块组

i)          重新生成一个方块组()

 

2)        方块组:BlocksGroup,具有以下功能

a)         旋转功能,给出旋转后的组

b)        移动功能,给出移动后的组

c)        显示功能,整体的显示可以和几个单个的显示不同

3)        方块:Blocks

a)         显示功能:形状、颜色等

b)        大小:高,宽(默认两个相等)

c)        擦除和显示

7月24日

学习c#第三天

27:一些基本的类库
答:功能强大的c#必须有一堆功能强大的类库支持,不然在处理问题的时候也会有心无力。显然c#不负众望,给用户提供了功能非常强大的一些类库。而支持文件操作的类库很完善,最游泳的两个是FileInfo类和DirectoryInfo类,他们都位于System.IO命名空间内部。处理这两个类的信息还有两个静态类:File和Directory。他们提供了文件的读写、创建、删除等功能,以及目录的读写、创建、删除等功能。
 
28:c#中的流 
答:System.IO.Stream类可以处理大多数的任务,例如从文本文件、二进制文件、其他变量还是从internet上读取文件,他都可以胜任。需要处理自己的特殊类型的,只需要从他派生出来一个类然后再做相应的处理就可以了。
 
29:Windows.Forms编程
答:虽然现在的程序越来越多的是基于web的程序,但是单击的窗口编程依然具有重要性。c#提供了一套专门为窗口编程的类库。一个窗口是从System.Windows.Forms.Form继承出来。与传统MFC窗口编程的最大区别是:这里的整个窗口布局和属性等都是在代码里面编写的,不需要象以前那样资源和代码分离。而c#也提供了绝大部分普通控件的类库,用事件来管理他们的消息,非常方便。
 
30:编写测试程序。
答:为了检验最近的学习成果,编了一个Calculator.他具有的功能有:加、减、乘、处、倒数、开方等。界面如下。
7月21日

学习c#第二天

15c#是如何进行变长参数声明的?

答: 1c#号称总结了javac++的优点,那么变长参数的函数声明必然就是需要支持的。

2c#采用了params关键字来支持变长参数声明,而参数被填到一个数组中,例如:

              public void func(params int[] arr)

3) 如果各个参数类型不一致的话,可以使用public void func(params object[] arr)来声明

 

16c#中的强制类型转换如何?

答:和c#里面的其他部分一样,c#里面的强制类型转换语法要求更为严格。

1)  必须包含public static implicit operator或者public static explicit operator四个关键字的声明,缺少一个就会报错。

2)  显示转换其实是可以堪称implicit转换的一个特例,能隐式转化的一定可以显示转换。建议对implicit转换具有以下特点:不改变类的任何属性、不丢失数据等

 

17c#枚举型的特点

答:1c#枚举型全部都是从System.Enum类继承过来的,具有System.Enum类的所有接口。

2c#枚举可以定义自己的类型,但是不能是浮点的,默认是int

3)枚举默认的ToString()是自己的名字,如果按照int型输出才是他的值。

 

18c#中的预处理

答:1c#中减少、简化了c++里面很多的预处理,例如#include2)现在最常用的是预编译#define #if #endif等。3)还可以调用编译指令#warning #error4)一个比较常用的,为了编程方便的指令 #region#endregion

 

19c#中的委托delegate

答:委托在这里感觉有很重要的作用,因为他和事件event概念是联系到一块儿了。这里的委托更像以前系统里面的callback函数,也更像c++里面的函数变量,其实就语法角度来讲,感觉可以把它认为是一种声明函数的typedef,但是使用更方便。

    public delegate void func(object a, object b);

生成实例的话用  func fc = new func(p.f); 其中的构造函数必须是已经声明好的函数(如果是非静态函数,则要生成相应类的实例)

 

20c#中的事件event

答:在一般的windows编程中,都有消息处理机制,然而这些必须是和操作系统相关的,语言本身不具备消息处理。而在c#中,由于实现了和系统的分离,那么语言本身具备消息处理功能就成为可能,这就是c# event功能。他是基于委托的,声明如下:

       public event func et;

1) 可以看出,他有点象声明了委托的一个实例,实际上event更像是对相应委托的一个管理器,他可以添加(+=)、删除(-=)一个委托,还可以响应委托(上面例子调用委托的方法为et(a,b),他会按顺序相应所有委托,但是这个调用只能在类内部使用)。在此基础上进行消息管理机制,将会非常的方便。

2) 由于一种事件只能相应自己的委托,那么要具有通用性,就必须有通用的格式,在.net框架中,定义了一个通用委托和事件:

       public delegate void common(object sender, EventArgs arg);

通过System.EventArgs类派生出来的类,可以用来传送消息内容。

 

21c#注释使用xml文件

答:1)为了更方便的生成文档,c#允许在注释的时候使用专用的 ‘///’来作为 xml文档的标记,这种注释一般用在类前面、函数前面、命名空间前面等,在编译器选项上做适当的设置,编译后就自动会把这些注释生成xml文档。

2)  现在用的人可能不多,因为在达到vs2005的时候,把xml=>web page这个选项去掉了。

 

22c#中使用命名空间using

答:大部分情况下,这里的命名空间和以前的c++是相同的,但是同样的功能更强大、更方便。在c#里面想使用另外一个程序集的时候,只需要两个简单的过程:a)add reference添加相应的dll或者lib等。b)使用using包含里面的内容。 简单的两步就可以调用里面的所有东西,而且可以跨语言。 一个小技巧:

    namespace One.Two.Three

    {

    }

       等价与

    namespace One

    {

        namespace Two

        {

            namespace Three

            {

            }

        }

    }

 

23c#中的Type

答:1c#是很强大的,所以他有System.Type类,再也不用象在c++里面那样为描述类型而犯愁了。

2)有三种方式可以得到一个对象的Type,编译时得到(typeof),运行时得到(obj.GetType()),通过字符串名字得到(Type.GetType(str))Type对象的内容非常丰富,基本上包含了类的所有信息。

3c#如何能够得到他的类型,这个原理还不清楚,不过肯定很有意思

To Be Continued …..

 

24c#中的动态生成对象,或者叫后期绑定

答:既然c#中有Type类,那么动态生成对象就变得很轻松。可以通过名字字符串、类实例等等来生成新的对象,一句话,只要你有Type那么你就有新的对象。而c#是用System.Activator.CreateInstance来完成动态生成的。

 

25c#中的数组、链表、集合等封装

答:1)非常方便,所有的封装都集中在System.Collections命名空间里面,比较重要的有QueueStackArrayListSortedListHashTable等几个类,这几个类的内容都是以object为类型的,因此可以放任何东西在里面。在System.Collections.Specialized里面有几个特定的类,可以很方便的使用,例如:StringCollection

2c#里面所有的数组都是从System.Array派生出来的,因此具有他的所有接口。而且可以跨语言。

3)可以通过foreach来访问数组里面的内容,有些不能访问的类如果具有Ienumerator接口的话,可以通过System.Collections.IEnumerator类来访问相应的内容

 

26c#中的多线程

答:c#中的线程非常的方便,在System.Threading命名空间中有各种类来实现,生成一个线程如下:

            Thread t1 = new Thread(new ThreadStart(委托));

            t1.Start();

这样生成一个新的线程,完成委托的内容。另外可以用suspend()resume()来挂起和唤醒一个线程。对于共享资源,需要用lock来锁定一个资源,如下:

            lock (typeof(Class1)) //这样锁定一个类的所有静态成员

            {

            }

 

            lock (obj) //这样锁定一个变量

            {

            }

            lock (this) //锁定当前实例

            {

            }

 

 

7月20日

学习c#第一天

刚刚接触一门语言,所以就把他拿起来和c++比较,还是真有不少相同的地方,很多都是从c++里面发展过来的。就第一天的经验来说,最明显的就是把c++里面的继承发展成为这里的“接口”和“继承”两个概念。而多态、重载的概念简直和c++里面一模一样。下面把自己的理解写下来,熟悉c#的博友多多指点阿。

 

1c#c++总体上有什么不同?

答:1c#是一种纯的面向对象语言,不存在全局变量和全局函数,就连Main函数也是类内部的函数,只不过使用了public static 修饰符而已。

2c#改良了c++里面的很多吃力不讨好的部分,例如采用了垃圾回收的概念、从而去除了指针,各种声明也更严格、例如重载必须要用override关键字、对变量必须要赋初值,还有干脆把string类型作为一个基本类型,异常的处理也更为强大、可以跨语言处理异常,发展了c++里面的继承概念、抛弃了多继承、把他分为继承和接口两个概念。

 

一句话,c#功能更强大,也会使程序员更懒,以前程序员可以用记事本来编辑c++程序,现在想用记事本编辑c#程序估计不现实了。

 

2c#的数据类型和c++有什么不同

答:1c#的数据类型分为数值型和引用型,数值型包括基本类型和struct声明的结构的实例,引用类型包括string类型和class声明的类的实例,不管是数值型还是引用型如果不初始化都回给出一个编译错误。

2)数值型的数据是在堆栈上的,和c++里面的数值型是一样的。但是这里的数值型的大小是和环境无关的,例如不管在什么样的机子上int都是32位的。

3)引用型数据非常类似于c++里面的指针,只是自动回收而已。

 

3c#数组和c++有什么不同?

答:c#里面一共有三种类型的数组,第一种就是直接用类似 int[] a = new int[5];这样声明的单维数组。第二种是直接用 int[,] a = new int[3,4];这样声明的多维数组。最后一种是 int[][] a = new int[3][];这样形势的散列表。另外,c#中的数组本身就是一个整体对象,他知道自己的大小,当越界访问的时候会抛出异常。

 

4:循环和c++有什么样的区别?

答:c#里面多了一种循环,foreach循环,这个循环里的变量使用的是引用型的,所以如果改变其内容的话就会编译报错。例如           

foreach (int i in c)

                                 i = 3;

就会给一个error CS1656: Cannot assign to 'i' because it is a 'foreach iteration variable'错误

 

5switch语句和c++有什么区别?

答:基本一样,但是这里的switch语句的语法更为严格,必须具有break语句,不然编译报错。另外多了一个功能,就是这里可以添加goto case ;语句,但是如果这个goto设置不当的话可能会造成死循环。

 

6c#的异常和c++有什么区别?

答:1) c#的异常处理是基于.net框架的,因此采用c#程序抛出的异常用其他的程序语言也可以处理,大大的增加了程序的扩展性。

2)抛出的异常必须是System.Exception类的一个派生,不能是随便的一个类型。

3) 后面的处理catch必须顺序正确,不然会编译错误。

4) 比c++多了一个finally关键字,如下:

            try

            {

                   正常代码

            }

            catch ()

            {

                   出错处理

            }

            finally

            {

                   不管正确还是错误都要处理的

            }

学习c#第一天

7c#structclass有什么区别:

答:struct更像一个对基本类型的封装,因此他生成的数据位于堆栈上面。另外struct不支持继承相关的东西、不支持虚函数、不能从接口继承。总而言之一句话,struct就是为了对基本类型封装,要想做其他事情,请用class

 

8c#setget

答:就我的理解,感觉使用setget有点类似 functionattribute 之间的一种属性,他是为了不破坏类的封装所采用的折衷方法。重要的是,使用它就可以实现接口和功能、数据的分离,例如在 interface中声明某个量的getset,然后在其派生类中实现数据已经相应的代表意义,这样即使数据结构发生了变化,也不会影响他的接口。

 

9c#的重载操作符

答:c#去掉了c++中很多吃力不讨好的操作符重载,只保留了最常用的,例如+,-,*,/ >> << == !=等不会有歧义的。另外对[]操作符采用了 public int this[int index]这样的形势来替代。另外,加强了限制,比如 == !=必须成对出现。最后,所有的操作符重载必须是static修饰的。

 

10c#的继承和c++有什么区别?

答:1c#只有单继承,如果要实现c++里面的多继承,就必须使用 继承和接口两个概念。

2)增加了限制,增加了关键字。例如对于virtual函数的重载就必须使用 override关键字,派生类对普通函数的重载必须使用new关键字,抽象类的声明必须使用abstract关键字,防止派生必须使用sealed关键字。

3)由于是单继承,所以在判断两个类关系时候就变得简单,增加了 asis两个关键字, c = A is B是判断A是否在B的继承链上,如果在c=true,否则c=falsed = A as B,那么如果A is B d 是把A强制转化为B的引用,否则d = null4)在两个类之间直接进行强制转换的时候,转化失败会抛出异常。

 

11c# object类的基本函数ToStringEqualsGetHashCodeFinalizeReferenceEquals

答:在c#中所有的类都是由System.Object类派生出来,即使用户在使用一个新类的时候没有显示声明,编译器也会自动加上。而object有一些基本函数,例如Equals函数、ToString函数、Finalize函数、GetHashCode函数、ReferenceEqual函数。这些函数是每个对象都会遇到的。

1Equals函数是判断两个类是否相等,往往重载这个函数和重载operator == 操作符是等同的(string类中就是这么干的)。但是如果判断两个对象内容是否相等,还是用Equals比较好,operator == 可以用来判断引用是否相等。

2finalize函数是用来给垃圾回收器调用的。

3ToString函数很常用,不多说了。

4GetHashCode函数。感觉c#的一个比较方便的地方在于他可以很快生成一个hash表,System.Collections.HashTable类可以生成一个hash表,但是如果让他正常使用,就必须重载Equals函数和GetHashCode函数。

5ReferenceEquals函数感觉更像给调试用的,因为这里没有办法调用显示的指针,所以就用这个来判断两个引用是否指向同样的空间。

 

12string类型的特点

  1)在c#中,为了方便使用,专门对string类型进行了封装,为了同时考虑方便性和效率,采用了两个类:stringSystem.Text.StringBuild

       2string类型本身是存储在堆上的,而且一个string对象一旦生成,就不可改变。如果使用 + sub等操作,那么就会在堆上生成一个新的string对象,因此效率比较低。

       3)为了加快速度,string类使用了intern概念,有一个专门管理string的内存池(例如刚声明的常量字符串),在用户重新声明另外一个string的时候,他会先检查内存池中有没有相同的string,如果有就会给他一个引用。如果一个string是在动态生成的,例如 b = a + “cde’中的b,那么内存池中就没有他的存在。这时可以显示的调用string c = String.Intern(b)来把b的内容驻留在内存池中(这里是拷贝,bc指向不同内存),以后再声明和b内容相同的string时候,就会直接指向c的引用(c在内存池中,b不在,因此指向c而不是b)。

       4string类型的operator==Equals函数是完全等价的

       5)可以看出,string类在运算的时候有经常的拷贝字符串,这在比较大的字符串时是效率很低的,因此提供了System.Text.StringBuilder类。这个类方法是:先给他分配一个Capacity空间,默认是16个字符,然后每次大的时候Capacity自动加倍,3264128…其他的操作参见具体的函数

 

13c#的接口interface是什么概念

答:1c#剔除了c++里面的多继承概念,把它分为接口和单继承两个方面,这样更有利于程序的扩展,编程也更方便。一个类不能从多个类继承,但是可以从多个接口继承。

    2)接口更像c++里面的纯虚类,只不过没有virtual等关键字,派生类也不用override关键字。

    3)编译器对接口的检查更严格,如果在派生类中没有处理相应的接口,就会编译报错,如果没有带public关键字也会报错,如果继续派生没有使用new关键字也会报错。

 

14c#的索引器是什么概念?

答:类似下面的这种声明:public double this[int index],其实就是c++里面的operator[]操作符重载,但是由于这里的操作符重载必须用static声明,所以就只好给[]弄了一个特例。另外要注意在索引越界的时候,抛出一个IndexOutOfRangeException异常。

 

7月19日

开始学习c#

引用一个高手的话:
 
write by cash(天下第七)
2001.12.20
版权所有,翻录不究

代序

C#(独白):很多年之后,我有个名字叫做C#,任何一种语言都可以叫C,只要它足够强大,我不会介意别人怎样看我,我只不过不想别的语言比我更强大。
C#(独白):我还以为这世界上有一种语言永远不会过时,因为它太完美。在我出道的时候,我认识一种语言,因为它出生的时候办公室的窗外有一棵橡树,所以很多年以后,它有个名字叫java。
C#(独白):近年流行网络,到处都有电子商务,有电子商务的地方一定需要技术,有技术就会用到我,我是C#,我的功能是为技术人员提供服务,使他们能更快的开发产品。
VB.NET(自言自语):看你的年纪也二十出头了,这二十几年来,总有些语言是你想学的,或是有些语言你一直都学不会,有些语言太难,或者你一直想搞懂它,但是你不行。哈,又或者你觉得不值。其实学一门语言,很容易。我有个伙伴,它很友善,而且最近很热门,只要你随便花点心思,它一定可以帮你成为一个牛人,你尽管考虑一下。其实学一种语言也不是很容易,不过为了生活,有时候你不得不费点劲。
Anders Hejlsberg(独白):离开Borland之后,我去了这个公司,开发了另一种语言。
Bill Gates(独白):2月14日,情人节,每年这个时候,都会发生一些事,很多人体会到快乐,有更多的人则会感到更加孤独。今年,我带来了一个新产品。
Cash:不久前,我遇上一个人,送给我一个Copy,他说那叫VS.NET,用了之后,可以叫你忘记所有以前用过的开发工具。我很奇怪,为什么会有这样的东东。他说人最大的烦恼,就是选择太多,如果只给你一条路,你就别无选择,只能走下去。你说这有多开心。这套软件本来是打算送给你的,看起来,我们要再Copy一份了。
Coder(独白):对于太新潮的东西,我向来很难接受,所以这套软件我一直没有装。可能这套软件真的很有效,从那天晚上开始,Cash开始忘记了一些东西。

Coder:你还记得Dephi吗?
Cash:我想不起来了。
Coder:你还记的php吗?
Cash:我也不记得了。
Coder:你为什么老看那个杯咖啡?
Cash:因为很眼熟。

Coder(独白):那天晚上他玩到很晚,第二天大清早就走了。我不知道他为什么要拿那套VS.NET给我,但我看得出他很兴奋,每次有新的语言发布,他都会变得很激动。
Coder(独白):一个月以后,Cash去了一个很远的地方,那是他上学的地方,Cash曾经在那里生活了一段时间,有一天他们毕了业,Cash就从来没有去过。

Cash:能不能再快一些?
java:我现在只能这么快。
Cash:我以前好像见过你?
java:何止见过,我曾经是你最好的朋友,但是现在已经不是了,你还在这儿干什么?
Cash:前不久,我遇见一个人,他送给我一套软件,叫做VS.NET,用了以后,不管以前用过什么语言也会忘了,我很奇怪,为什么会有这样的东西,我用了之后发觉真的很有效,不知你有没有兴趣试试?
java:你知道MS和SUN的分别吗?MS,越来越不要脸;SUN会越用越心寒。
Cash:我们还会再见面吗?
java:不会!