1. 游戏与数学

    前段日子看了看 Pygame 的使用方法,其中看到一个之前从来没想过的东西,觉得很神奇,记录下来。

    物体与坐标

    熟悉 html、css,或者 Java GUI 甚至 Flash、Photoshop 的童鞋应该对定位并不陌生。在计算机中,常常使用坐标来对物体进行定位的。 例如,以 Flash 为例,Scene 左上角的像素点就是坐标的原点,而最顶部的像素构成的线是 x 轴,正方向向右;最左边像素构成的线是 y 轴,正方向向下。

    另外需要注意的是,哪一个像素点才是物体的参考点,一般来说是对象正方形区域,左上角的点作为参考点。

    通过将物体以一个(参考点坐标,长,宽)这样的形式来对物体进行定位,可以使得我们很方便的改变物体的位置。

    while True:
        screen.blit(dennis, (position_x, position_y ...

  2. Semantic Versioning

    Introduction

    Semantic Versioning 即语义化版本识别,是一套用来规范定义软件版本的规则。官网: http://semver.org

    Usage

    SemVer 的基本格式是 主版本号.次版本号.修订号(-先行版本号或元数据信息)

    1. 主版本号:当 Public API 做了向下不兼容的修改的时候,递增。
    2. 次版本号:当 Public API 做了向下兼容的修改的时候,递增。
    3. 修订号:修复了 Bug,但没有对 Public API 做修改的时候,递增。

    Details

    以下是 SemVer 的细致规则:

    1. 要使用 SemVer,首先你得有 公共接口 (Public API)
    2. SemVer 采用 X.Y ...

  3. Team and manager

    团队与管理者

    何为团队?

    首先,一个人肯定不是团队,那只是一个个体。而两个人也不能算是一个团队,那是两个相互支撑。

    一个团队至少需要三个人,这样就有了团队的基本特性:①主从 ②监督 ③责任

    当然,这并不代表一个人或者两个人的开发行为并不能成功。

    一个团队,所有成员的目标应该一致,同时也需要一些制度来制约每个成员的行为,以求团队工作效率最高。

    任何团队,都需要一个管理者。作为团队的管理者,勇于承担责任是最基本的素质,管理者未必是团队中能力最强的人,但管理者应该对团队负责。当团队项目失败了,管理者的责任应该是最大的,而不是团队的其他技术人员,因为团队是由管理者所管理的,技术人员的进度、产品的质量也是由管理者所把握的。

    对于项目的成败,主要由以下两个方面进行评估:

    1. 项目完成的质量
    2. 项目完成的时间

    对于“项目完成时间”这一评估标准,一般需要在项目开始之前就做一些估算,经验丰富的工程师可有尽可能接近预计的工期,但没有办法保证工期绝对合理。也因此,项目总是会因为进度而修改工期。所以团队的管理者需要学习如何掌握工期,这需要一定的时间来成长。


  4. Lounger created methods

    懒人造就了方法

    人的精力终归是有限的。提出问的解决方法才是影响做事成效的根本问题。

    在早起的汇编语言中,GOTO语句使用非常频繁,将GOTO语句写到另一个文件中十分不便,因此开发人员习惯将程序写在同一个文件中。久而久之就养成了这样的习惯,并一直延续到高级语言出现之后。

    但随着程序功能日益复杂,代码自然也增多,几千行代码的程序也不罕见了,如此长的代码,PageUp/PageDown 自然成为开发人员最喜欢的按键了。

    但这世界上总有一些懒人,他们疲于天天的 PageUp/PageDown,他们打破习惯的约束,将程序拆分成多个文件编写,这就是“单元文件”的开发方式。“单元文件”使得程序容易修改维护。

    “单元文件”的概念出现之后,很快也有“模块”的概念,把一个大模块分成许多小模块,把小模块分成更小的模块,每个模块对应一个单元,于是历史上的“单文件代码”被拆分成许多的小文件,每个文件由一个团队不同的开发人员完成编写,促进了团队开发模式,也提高了程序的开发效率。

    “单元文件”和“模块”的概念出现之后,便有了“结构化编程”的概念,“结构化编程”实际上也是我们所说的 ...


  5. Avoid Useless default constructor

    避免无用的默认构造函数

    C++允许在构建对象的时候使用默认构造函数。这一点为编程带来了一定程度上的便利,但同时也带来了一些实现陷阱。

    有的时候使用默认构造函数所创建的对象反而没有实际意义,例如一个学生,在没有姓名的时候就是一个无意义的对象。

    一般而言,无需任何数据就可以建立的类可以包含默认构造函数,而需要数据的类则不可以包含默认构造函数。然而没有默认构造函数的类在实现上会有很多限制:

    限制一:创建数组

    如一个类没有默认构造函数,在创建数组的时候没有一种对数组所有元素赋参数的方法,因此数组将创建失败。

    对于这个限制,有几个办法可以回避

    • 回避方法一:对于非堆上的数组,可以在创建时提供必要的参数:
    Student list[] = { Student(Bruce), Student(Steven)};
    

    然而这个方法的缺点很明显,它只适用于非堆数组。

    • 回避方法二:使用 typedef 定义一个指针
    typedef Student* Stup;
    StuP myStu[10];
    Stup * list = new StuP[10];
    

    定义完毕后再对每一个元素进行赋值。

    但这个方法存在两个缺点,一是在删除数组的时候需要释放数组中所有元素的内存,否则会引起程序内存泄漏;二是这种方法会增加额外的内存空间消耗 ...


  6. Polymorphism and Array

    不要对数组使用多态

    C++ 中的类继承特性使得你可以通过基类引用或指针来对派生类进行操作(多态)。同样的,这一特点也同样使用于对象数组。但请永远不要对对象数组使用多态。

    假设有这样一个对基类数组进行访问的函数:

    void printObjs(Base[] obj, int num){
        for (int i=0;i<num;++i){
            cout << obj[i];
        }
    }
    

    同时有基类 Base 的派生类 Child 。若程序中出现:

    Child myObj[10];
    // 对 myObj 所有元素初始化
    printObjs(myObj, 10);
    

    这样的代码会产生与你所设想不一样的执行结果。原因很简单,因为 Base` 与 ``Child 的结构不一样。也就是说 Base 对象与 Child 对象所占用的内存空间不一样 ...


  7. C++-style Type Conversion

    优先使用 C++ 风格类型转换

    大多数程序员都认为 C++ 是在 C 的基础上引入面向对象概念。这一观点并不完全准确。C 语言是一中简洁优雅的语言,若仅仅引入面向对象概念,由怎么会有众多编写 C++ 的大师认为自己对 C++ 的了解并不深呢?可想而知,C++ 比单纯的 “C 语言 + 面向对象” 还要更复杂得多。

    C++ 在设计的时候同样也考虑到程序设计过程中的类型转换问题,但C语言风格的类型转换对于 C++ 来说过于简单粗暴(通过括号及目标类型来进行转换)。试想想,C 中只有基本数据类型以及用户自定义的 struct 结构,因此这样“简单粗暴”的类型转换对C来说是足够,但对引入面向对象之后的 C++ 却不然,至少 C++ 还有着无数程序员自定义的类。因此 C++ 也拥有自己的类型转换操作符。

    除了上面所说的原因,还有另一个优先使用C++ 风格类型转换操作符的原因是 ...


  8. Reference or Pointer?

    引用还是指针

    在C++中,变量有着两种存在形式:引用与指针。

    引用与指针在使用方式上完全不同,但它们的功能都是一样的。都是用来间接引用其他对象。

    为了更清晰在什么场合下更适合使用引用或是指针,以下做一个整理:

    首先,引用不同于指针,不能指向空引用。这也就是说,引用必须指向某个对象。由这一点,我们可以知道,当所指向的对象可能有空引用的情况出现时,就必须使用指针,而当对象永远都不可能称为空引用时,才可以使用引用。

    其次,引用在定义的时候必须对其初始化,而指针没有这样的限制。所以当存在有不同初始化可能的时候应用使用指针,而不能使用引用。但这点也意味着引用的代码效率要比指针高,因为使用指针之前,必须对指针进行合法性验证,否则会出现对空指针进行操作的错误。

    另外,引用所指向的对象一旦初始化之后就不能再改变指向的对象,而指针也没有这样的一个限制。因此以下的代码中引用与指针所做的事情是有本质上的不同

    string s1("Nancy");
    string s2("Clancy");
    string& rs = s1;
    string * ps = &s1;
    rs = s2;
    ps = &s2 ...

  9. Git and Workflow

    Git 和 SVN/CVS

    大学两年里,接触了三种版本控制系统:

    1. 第一个接触是 SVN。学子天地 网站目前使用的版本控制器就是 SVN。作为第一个接触的版本控制系统,SVN 给我一个很新鲜的感觉。SVN 是集中式的版本控制系统,即版本仓库是在一个服务器上,所有开发者从这个“中心版本库”里 checkout, update,然后向“中心版本库“ commit 自己的修改。
    2. 接触 SVN 大约半年之后,开始接触 Git。目前我自己的私人项目都使用 Git 来管理代码,并且在 Github 和 Bitbucket 上托管。Git 不同于 SVN,它是一个分布式的版本控制系统。所谓分布式是指每个开发者都拥有自己的代码仓库,并且可以从其他开发者(也包括服务器)拉取代码更新,Git 和 SVN ...

  10. Smart Pointer

    Introduce to Smart Pointer

    In computer science, a smart pointer is an abstract data type that simulate a pointer while providing additonal features. -- [WikiPedia](http://en.wikipedia.org/wiki/Smart_pointer)

    In the C++ language, smart pointer implements as a template class and override the behaviour of raw pointer, such as ...


Page 1 / 2