Carbide.C++快捷方式的说明
编辑相关
Ctrl+ ↓ Ctrl+↑ 在编辑区上下滚动(滚动滑块)
Ctrl+ ← Ctrl + → 向前向后移动一个单词
Ctrl+ Shift + ↓ Ctrl+ Shift + ↑ 向上向下移动一个段落(可以方便的在函数方法中滚动)
Ctrl+G 搜索工作区中的声明
Ctrl+ Shift +G 搜索所有引用
Ctrl+ Shift +S 保存所有文档
Ctrl+F 查找替换
Ctrl + J 增量查找(根据动态键盘输入进行动态匹配)
Ctrl + k 查找替换下一个
Ctrl + L 转到指定的行号
Ctrl+ Shift + F4 关闭所有编辑窗口
Ctrl + SHIFT + P 匹配对应的括号
CTRL+SHIFT+X 将选中的小写转换为大写
CTRL+SHIFT+Y 将选中的大写转换为小写
Ctrl+M 将当前窗口在最小化和最大化之间切换
Ctrl+Q 定义最后编辑的地方
Ctrl+O 快速显示 OutLine
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表
Ctrl+` 在c/c++中非常有用的功能 打开相关的源文件或头文件
Ctrl+D 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交换位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交换位置(同上)
编译、运行
Ctrl+B - 重新编译所有项目.
F11 - 调试(Debug)当前项目.
Ctrl+F11 - 运行当前项目.
Ctrl+. and Ctrl., - 转到下一个/前一个提示项目。当编译器为我们生成了很多编译警告等信息的时候,这个功能将发挥区大的作用。
Ctrl+Shift+B - 切换当前行的断点状态。注意,该快捷键仅仅在调试界面下是可用的,在Symbian开发界面下是不可用的。
Ctrl+Alt+B 程序编辑目标项目
调试
F5 - 进入当前行函数.
F6 - 执行当前行.
F8 - 继续执行.
Ctrl+R - 执行到当前行.
重构相关
Alt + shift + r - 变量名函数名重构
阅读源码
F3 - 查看变量的声明
F4 - 查看某类的继承层次关系
Ctrl + T 快速查看类的继承关系
导航相关
F2 - 使编辑视图获得焦点
ALT+SHIFT+W 当焦点在编辑区的时候显示源文件的导航视图(Outline,Navigator,C++ project)
Ctrl+F6 ,Ctrl+ SHIFT+ F6 在编辑视图中对打开的文档进行进行切换(类似于WINDOWS的 ALT+TLB和 ALT+SHIFT+TBL)
Ctrl+F7,Ctrl+ SHIFT+ F7 对全局视图进行切换
Ctrl+F8 ,Ctrl+ SHIFT + F8 - 界面组的切换 ,这个快捷键可以切换Symbian界面组和调试(Debug)界面组。
开发环境:
Vc中编译:
第一步: 在/group:中执行: bldmake bldfiles 生成makefile
第二步 : abld makefile vc6
第三步 : 打开工程文件 ,编译,连接成功后.并附加到
epoc.exe,( C:/Symbian/8.0a/S60_2nd_FP2_SC/epoc32/release/wins/udeb/epoc.exe)
通过命令行构建和编译:
第一步: bldmake bldfiles
第二步;生成目标版本
模拟器版本:abld build wins (urel)udeb 在命令行模式敲入epoc.exe启动模拟器
目标设备版本: abld build thumb urel(udeb) 通常目标平台选择 armi 和 thumb
第三步:打包应用程序
Cd sis
Makesis yourproject.pkg
Devices 命令(切换平台sdk)
Devices: 显示安装的sdk
A.Devices –setdefault @sdk平台标示
B . 修改C:/Program Files/Common Files/Symbian/devices.xml
Symbian
6.0 ,8.0 向下兼容 6.0的可在8.0上运行,但8.0的不能在6.0上运行
9.0
Carbide c++ :
F3 : 查看声明
左侧边框双击下断点 或右击菜单
Ctrl + / : 注释, Alt + / : 显示成员列表
Ctrl+shift+L : 显示所有快捷键
Ctrl+F8 :切换debug / Carbide C++模式
F11:调试 F5: step into F6: step out F8: resume
Ctrl+B; build project
Ctrl+F11:run
Ctrl+Shift+F 格式化一段代码
编辑代码风格:菜单栏window/preferences..对话框中
c/ c++code style
Ctrl+D 删除一行
Alt + 方向键: 移动代码,将一行代码向上或向下移动
Alt+Ctrl +方向键: 复制本行代码到指定方向
选中类名后Alt+shift + R : rename后重构
Ctrl+shift+X 转换成大写
Ctrl+shift+Y 转换成小写
Ctrl+M :全屏切换
LeaveScan:
for /R %%i in (*.cpp) do leavescan %%i >> leavescan.txt
T类
!,分配在栈空间(stack)
2.没有析构函数,(没有指针成员变量 )
3.通常不重载赋值运算符
C类
1.在堆上分配内存(heap)
2.从CBase继承过来,分配内存使用new ( ELeave )
3.默认情况下赋值运算和拷贝构造是私有的 (不允许拷贝,一般使用引用和指针)
推荐使用引用的方式
4.通常需要使用两段构造的方法来进行一个构造
R Class:
1.通常也是在栈上分配内存
2.R类和服务器的资源相关,通常使用完毕后需要close(),或者free()
和系统服务调用有关. 相当于服务器的一个句柄,
Example: RFs - A handle to a file server session
Location: f32file.h
Link against: efsrv.lib
注意包含头文件,和向mmp中添加库文件(LIBRARY efsrv.lib), 查sdk help
M类
1. 用于多重继承
2. 通常只定义类的接口没有实现方法 (一般是纯虚函数)
3. 没有数据成员
User: eave(int) throw
void FunctionL()
{
User: eave(-1); //throw -1;
}
void Function2L()
{
FunctionL()
}
void Function3()
{
//相当于TRAPD(err,Function2L());
TInt err;
TRAP ( err, Function2L() ); // try { Function2L(); }
If ( err != KErrNone ) // catch(TInt err){ }
{
}
}
// new ELeave overload 伪代码
new (ELeave)
{
Void *p = new Class()
If(p)
{ memset(0, sizeof(p) );}
Else
{ User: eave(NoFreeMemory);}
}
//抛出异常
User: eave(TInt)
User: eaveIfError(TInt) //通常用于把返回错误代码的函数转换为异常抛出函数
//捕获异常
TInt err;
TRAP(err,LeaveFunctionL());
TRAPD(err,LeaveFunctionL()); //集成了对err变量的定义
// new (ELeave) 运算符
1. 当内存不足的时候会抛出异常
2. 如果分配成功,对内存进行初始化为0
野指针: 当声明一个指针时,它的值是随机,不知道指向哪,
有可能指向系统代码区,如果此时访问,程序会崩溃.
如: char* pCh ; // pCh的值是随机的
pCh = new char; //此时pCh内有一个明确地址
delete pCh; //释放 pCh指向的空间,但pCh的值不变
pCh = NULL; //必须置为NULL ,因为如果之后在析构函数
//中delete时,如果pCh没被置为NULL,
//还指向原来的空间
//此时delete,就会造成二次释放程序就会崩溃,
//delete NULL是安全的
//但delete 同一地址(除0之外),程序会崩溃
//异常捕获的原则
1. 使用异常捕获比较耗费系统资源,尽量减少TRAP和 TRAPD的使用
2. 推荐在程序的入口进行异常捕获和处理(对顶层函数进行异常捕获处理)
//清除栈使用原则:
1. 分配内存之后立刻压入清除栈
2. PushL 和Pop 一定要匹配
3. 清除栈弹出的顺序 要按照后进先出的原则 进行弹出
4. PushL(TAny* aAny) 和PushL(CBase * aClass) 可以混合使用
TClass * classs1 = new (ELeave) TClass();
//CleanupStack: ushL(TAny* any)
CleanupStack: ushL(class1);
CClass * class2 = new (ELeave) CClass();
//CleanupStack: ushL(CBase* class)
CleanupStack: ushL(class2);
//do something
CleanupStack: opAndDestroy(2);
// PopAndDestroy的内部实现:
//C类的删除 调用 delete class;
//TAny 删除调用 User::Free any;
5.不要将类的成员变量放入清除栈中,只要在类的析构函数中释放就可以了,否则可能会造成二次释放,
如果有NewL(),成员变量应使用NewL()方法.
6.对于R类,一般使用CleanupClosePushL(),
CleanupReleasePushL(),CleanupDeletePushL()等 函数,用完之后CleanupStack: opAndDestroy();
//两段构造
1. symbian规定C类的构造函数不允许发生异常,通常使用两段构造来构造一个C类。
CMyClass* mycls = new (ELeave) CMyClass;
CleanupStack: ushL(mycls);
Mycls->ConstructL();
//do something
CleanupStack: opAndDestroy();
2. 通常我们为C类提供NewL和NewLC两个静态方法实现两段构造(NewL通过NewLC实现)
3. 如果我们的C类提供了NewL和NewLC方法,应该把构造函数和ConstructL()方法设置 为私有或者保护。
4. NewL方法通常用于初始化类的成员变量,NewLC通常用于初始化局部变量.
5. 当我们从某个C类继承的时候我们需要在我们的ConstructL()方法显式的调用基类的ConstructorL()
(此时的基类的构造函数和ConstructL()属性为Protected)
MyClass::ConstrucL()
{
MyClassBase::ConstructL();
}
descriptor
| type(4bit) | legth | data (ptr) |
以下descriptor 可以查看SDK
//这两个是所有描述符的基类,不能实例化
TDesC (不可修改描述符的基类)
TDes(可修改描述符的基类)
TPtr
TPtrC
TBuf
TBufC
HBufC
Example:
TPtr
#if defined(_UNICODE)
typedef TPtr16 TPtr;
#else
typedef TPtr8 TPtr;
#endif
//描述符
//描述符读写特性
1. 可修改描述符, 继承于TDes
TBuf<n>
TPtr
2. 不可修改描述符 继承于TDesC
TBufC<n>
TPtrC
HBufC
//描述符使用方式
1. 缓冲区描述符,在栈上使用
TBufC<n> 可以进行赋值操作,不能修改,通过Des()方法可以转换为可修改描述符,TBufC中:TPtr Des();
没有Copy()方法
TBuf<n> 没有Des()方法, void Copy(const TDesC& aDes);
即可以进行赋值操作也可以修改
2指针描述符,类似于指针可以指向缓冲区描述,堆描述符或其他指针描述符
TPtr可修改指针描述符 (可以修改和赋值)
TPtr的Copy方法(可接受任意类型的描述符):
void Copy(const TDesC8& aDes);
a.通过已有的可修改的指针描述符初始化(TBufC或HBufC的Des()方法
b.通过字符串缓冲区初始化,TUint16 buf[20]; tPtr(buf,20);
TPtrC (不可以修改和赋值指针描述符)
没有拷贝方法
可以通过任意描述符进行初始化(可以指向任意描述符)
二者都提供了Set()方法可以修改其指向,但Set()方法重载不
同,TPtr的Set()有void Set(TPtr16& aPtr);
和void Set(TUint16* aBuf,TInt aLength,TInt aMaxLength);
TPtrC的Set()有: void Set(const TUint16* aBuf,TInt aLength);
和 void Set(const TDesC16& aDes);
3. 堆描述符
HBufC (HBufC8, HBufC16)
在堆上分配内存 可以通过其静态方法创建堆描述符
(HBufC::NewL(size),HBufC::NewLC(size) )
SDK中 NewL()和NewLC()的声明:
static HBufC* NewL(TInt aMaxLength)://注意返回的是HBufC类型的指针
static HBufC* NewLC(TInt aMaxLength);
可以通过已有的描述符创建堆描述符 使用TDesC类的AllocL()方法.
Sdk中: AllocL()声明: HBufC16* AllocL() const;
用法和TBufC<n> 一样,同样提供了Des()方法转换为可修
//注意TBufC没有Copy()方法,但可以赋值, TDesC也没有,
TBuf和TDes有Copy()方法,最好声明一个TBuf
改描述符.如果要修改HBufC,先用Des()取得可修改指描述
符
TBufC<50> stackBuf(_L("hello symbian!"));
HBufC* heapBuffer = HBufC::NewLC(50);
TInt length = heapBuffer->Length(); //current length is 0
console-> rintf(_L("length = %d/n"),length);
TPtr ptrHeap(heapBuffer->Des());
ptrHeap = stackBuf; //ptrHeap.Copy(stackBuf);
console-> rintf(_L("heapBuffer = %S/n"),heapBuffer);//注意没有&
CleanupStack: opAndDestroy(); //别忘了
可以通过ReAllocL()动态增加内存
使用ASSERT()断言
1.CArrayPtrSeg<TTask> *iTaskArray;
At(),Delete() (只删除容器中的元素),AppendL(),InsertL(),
ResetAndDestroy()(删除容器中元素所指的对象并Reset),
Count()方法
CArrayPtrSeg容器内存放的是指针
2.CArrayFixSeg<TTask> *TaskArray;
方法和CArrayPtrSeg基本相同
CArrayFixSeg容器内存放的是对象本身
3.RArray<TTask> iTaskArray;
用Remove()方法而不是Delete()
用iTaskArray[index]而不是iTaskArray.At(index)
用Remove()而不是RemoveL()
InsertL(const TTask& aTask,TInt aIndex)
参数的顺序与1.和2.不同
析构函数中:
4.RPointerArray<TTask> iTaskArray;
方法和RArray基本相同,除了Remove()方法和析构函数中
RPointerArray的Remove()只是移除数组内的元素,还要将
元素指向的空间释放
void CTaskManagerRPointerArray: eleteTaskL(const TInt aIndex)
{
TTask* task = iTaskArray[aIndex];
iTaskArray.Remove(aIndex);
delete task;
}
CTaskManagerRPointerArray::~CTaskManagerRPointerArray()
{
iTaskArray.ResetAndDestroy();
iTaskArray.Close();
}
RPointerArray中存放的是指针.
动态数组
//CArrayX
1.存放固定大小元素
CArrayFixFlat //线性结构
CArrayFixSeg //链表结构
存放固定大小的元素的动态数组,会拷贝对象的副本到数组
内部
2. 存放指针(元素大小不固定)
CArrayPtrFlat //线性结构
CArrayPtrSeg //链表结构
仅仅存放指针到动态数组,对象本身拥有自己的内存单元,
在数组销毁之前需要调用ResetAndDestroy();
删除单个元素需要首先获取元素的指针,对数组元素执行
删除后,记得释放元素本身的内存单元
//RArray and RPointerArray
//相对CArrayX比较高效灵活,推荐使用这两种数组
RArray: 存放固定大小的元素(通常存放T类,或基本类型)
消毁的时候调用Close()方法.
RPointerArray:存放任意类型指针 (不能存放C类)
消毁的时候,首先应该调用ResetAndDestroy()方法然后调用
Close().
//描述符动态数组
1.通用描述符数组
CDesC16ArrayFlat
CDesC16ArraySeg
拷贝描述符数据副本到数组,较为安全,缺点是比较浪费内存
//指针描述符数组
CPtrC16Array
它可以接受任意类型的描述符,在内部创建一个TPtrC
指向传进来的描述符
只拷贝描述符指针(TPtrC), 较为节省内存,缺点是在外部数
据销毁或者修改时有安全隐患