C++的学习笔记

@.h@ 头文件:由版权版本声明、预处理块、函数和类结构组成。

/**
 * 版权版本声明
 * 文件名:test.h
 */

#ifndef __TEST_H__   // 预处理块
#define __TEST_H__

// 全局函数
int add(int x, int y);

// 类结构
class Test
{
public:
    Test();
    ~Test();
    void sayHello(const char * str);
};

#endif

@.cpp@ 定义文件:由版权版本声明、头文件引用、函数实现休

/**
 * 版权版本声明
 * 文件名:test.cpp
 */

#include      // 标准库头文件
#include "test.h"       // 非标准库头文件

int add(int x, int y)   // 函数实现体
{
    return x + y;
}

Test::Test()            // 类实现体
{

}

Test::~Test()
{

}

Test::sayHello(const char * str)
{
    std::cout << "Hello " << str << std::endl;
    std::cout << "10 + 15 = " << add(10 + 15) << std::endl;
}
</pre>

    

总结:头文件的作用是隐藏实现体,通过头文件来调用库(.so)功能,加强类型检查,出现声明不一致时编译器报错。

技巧:通过头文件与声明文件放在不同的文件夹,如:include、source,对外提供时只需要提供include与编译后的.so库。

</section>

2.1: *空行* ,为了保持代码美观,函数与函数之间应该保持空行,函数内也应根据需要空行。

2.2: *代码行* ,一行代码应该只完成一件事,如定义一个变量,控制结构也应该使用 @{}@ 把代码包起来。

2.3: *代码行内的空格* ,在运行符与变量之间应该保持空格。

2.4: *对齐* ,控制结构的 @{}@ 应各占一行。

2.5: *长行拆分* ,一行代码的数量应该保持在70~80个字符,拆分时操作符应该放在新行的句首。

2.6: *修饰符的位置* ,修饰符应该靠近变量名,如 @char *name;@ 。

2.7: *注释* ,统一使用Doxygen的规范。

2.8: *类的版式*

2.8.1:以数据为中心的版式,private类型写在前面,重点关注类的内部结构。

2.8.2:以行为为中心的版式,public类型写在前面,重点关注类的行为,接口方法。

3.1:共性规则,变量使用 @名词@ 或 @形容词+名词@ ;全局函数使用 @动词@ 或 @动词+名词@ 。

char * name;                        // 变量使用名词
char * firstName;                   // 形容词+名词

void setName(const char * name)     // 全局函数使用动词+名词
{

}

void Student::sing(void)            // 类的成员函数使用动词 
{

}

4.1 运行符优先级

运行符太多,在复杂的语句中应使用 @()@ 把要先运行的代码包起来,如: @if ((a == 10) && (b == 10))@ 。

4.2 if语句中的零值比较

if (flag)
{
    // flag为布尔值的正确写法
}

if (x == 0)
{
    // x为整数值的正确写法
}

if (p == NULL)
{
    // p为指针时的正确写法
}

if (f < 0 || f > 0)
{
    // f为不等于0的浮点数,浮点数比较时应使用比例符号,而不是==
}

4.3 循环语句中的效率问题

for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 100; j++)
    {
        // 高效率的写法
    }
}

for (int i = 0; i < 100; i++)
{
    for (int j = 0; j < 5; j++)
    {
        // 低效率的写法
    }
}

// 如果循环体内出现条件判断语句宜将条件判断语句放到循环体外。

4.4 switch语句

switch (var)
{
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    default:        // default应该写完整,即使没有实现。
        break;
}

5.1 常量定义

可能有两种方式来声明一个常量,不过最好是使用 @const@ 来定义一个常量,而不使用 @#define@ 来定义常量。

#define MAX     10;     // 使用宏定义一个常量
const int MAX = 10;     // 使用const定义一个常量,有数据类型

需要对外公开的常量定义在头文件头部,不需要公开的定义在定义文件头部。

5.2 类中的常量

class Test
{
    const int X = 100;  // 错误,类中的常量不能在定义的时候初始化。
    Text();
    ~Test();
}

Test::Test()
    :X(100)             // 正确,类中的常量应该在构造函数的时候初始化。
{

}

6.1 函数命名规则

应使用首字母小写,形容+动词或动词的命名方式。参数使用完整的参数列表。

void add(int x, int y);
void sayHello(const char *str);

6.2 函数参数规则

如果是指针传递应加 @const@ ,值传递加 @&@ 。

void sayHello(const char *str);         // 指针传递

void add(int x, int y, int &count);     // 值传递

Ubuntu安装SublimeClang插件

$ curl -kL http://xrl.us/pythonbrewinstall | bash
$ source "$HOME/.pythonbrew/etc/bashrc"
$ pythonbrew install --configure="--enable-unicode=ucs4" 2.6
# 这一步会安装错误,修改$HOME/.pythonbrew/dists/Python-2.6.tgz压缩包中的Makefile.pre.in文件,搜索[-DSVNVERSION=\"`LC_ALL=C svnversion .`\"]改成[-DSVNVERSION="\"`LC_ALL=C svnversion .`\""]后重新执行pythonbrew install --configure="--enable-unicode=ucs4" 2.6安装.
$ ln -s $HOME/.pythonbrew/pythons/Python-2.6/lib/python2.6/ <your Sublime Text 2 folder>/lib/python2.6
$ sudo apt-get install clang
$ cd $HOME/.config/sublime-text-2/Packages/SublimeClang/src
$ mkdir build && cd build
$ cmake ..
$ make

Ubuntu编译Box2D物理引擎

@https://code.google.com/p/box2d/@

$ sudo apt-get install cmake libglu1-mesa-dev libxi-dev
$ cd $BOX2DPATH/Build
$ cmake -DBOX2D_INSTALL=ON -DBOX2D_BUILD_SHARED=ON ..
$ make
$ sudo make install // 安装到 /usr/local/include/Box2D
$ ./$BOX2DPATH/Build/Testbed/Testbed

Cocos2d-x之tests工程在Ubuntu上运行

@$ sudo apt-get install libglfw2 libglfw-dev libzip2 libzip-dev@

$ cd $COCOS2DX_ROOT/Box2D/proj.linux                    // 进入对应的linux工程
$ make                                                  // 这一步是编译libbox2d.a静态库
$ mkdir -p $COCOS2DX_ROOT/lib/linux/{Debug,Release}     // 创建linux工程存在库文件目录
$ cp libbox2d.a $COCOS2DX_ROOT/lib/linux/Debug          // 复制库文件到Debug目录
$ cd $COCOS2DX_ROOT/chipmunk/proj.linux                 // 进入对应的linux工程
$ make                                                  // 这一步是编译libchipmunk.a静态库
$ cp libchipmunk.a $COCOS2DX_ROOT/lib/linux/Debug       // 复制库文件到Debug目录
$ cd $COCOS2DX_ROOT/CocosDenshion/proj.linux                    // 进入对应的linux工程
$ make                                                          // 这一步是编译libcocosdenshion.so动态库
$ cp libcocosdenshion.so $COCOS2DX_ROOT/lib/linux/Debug         // 复制库文件到Debug目录
$ cp ../third_party/linux/fmod/api/lib/libfmodex.so $COCOS2DX_ROOT/lib/linux/Debug      // 同时复制libfmodex.so
$ cd $COCOS2DX_ROOT/cocos2dx/proj.linux                 // 进入对应的linux工程
$ make                                                  // 这一步是编译libcocos2d.so动态库
$ cp libcocos2d.so $COCOS2DX_ROOT/lib/linux/Debug       // 复制库文件到Debug目录
$ cd $COCOS2DX_ROOT/tests/test.linux                    // 进入对应的linux工程
$ make                                                  // 这一步是编译libcocos2d.so动态库
$ ./cocos2dx-test                                       // 运行测试工程

Cocos2d-x之CCSpriteFrameCache

配合plist文件加载一张大图片中的某个区域

@.plist@ 格式


<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">


    texture
    
        width
        图片的宽度
        height
        图片的高度
    
    frames
    
        每帧的键值,使用spriteFrameByName获取
        
            x
            X坐标
            y
            Y坐标
            width
            
            height
            
            offsetX
            X坐标偏移
            offsetY
            Y坐标偏移
            originalWidth
            原宽
            originalHeight
            原高
        
    


使用CCSpriteFrameCache载入plist与图片

CCSpriteFrameCache * cache = CCSpriteFrameCache::sharedSpriteFrameCache();

cache->addSpriteFramesWithFile("plist文件", "图片");

CCSprite::spriteWithSpriteFrame(cache->spriteFrameByName("plist中定义的key的键值"));

CCSprite::spriteWithSpriteFrameName("plist中定义的key的键值"); // 直接也可以

// 使用完以后记得清空释放内存
CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();

// 根据plist清空对应的图片
CCSpriteFrameCache::sharedSpriteFrameCache()->removeSpriteFramesFromFile("plist文件");