1. .h文件要用#ifndef-#endif包住,.cpp开头要有using namespace std声明;
2. class命名首字母大写,成员变量应当以m_开头;
3. 如果class成员函数没有改变成员变量的值,应当声明为const函数;
4. 定义对象时候最好用ClassA a(...);而避免ClassA a=ClassA(...),省得多创建临时变量;
5. 一般只有返回值为指针的函数会给返回值加const,否则加了也没意义;
6. 友元函数的一大作用就是操作符重载时候反转操作数的顺序;
7. const修饰整个函数时候只能用于修饰成员函数;
8. 当函数体在类声明中实现时,该成员函数自动成为inline函数;
9. 自定义namespace时,class.h和class.cpp中的内容都应被包在namespace中,main.cpp中才用using namespace yournamespace;
10. 重载了=,不代表可以用+=;
11. class中的static member一般不能在类声明中初始化,而是在.cpp中单独初始化,并且要指明类型,如 “int myclass::count=0;”。但如果static member是const int或者const enum,可以在.h中初始化。static member function在声明处加static,定义处不要加static;
12. 拷贝构造函数和重载赋值操作符应该同时需要,重载=函数的内容包括copy构造函数,但还需要多一些this判断和delete左值new的内容的动作和返回值。参考stringbad.cpp。
13. 构造函数中对const类型和“引用”类型的成员赋值的方法:不能在构造函数内部赋值,只能用member initializer list即构造函数后面跟的()来初始化。对于其他类型的成员随意,但如果成员自身也是一个类对象的话,这样做效率更高。另外对于派生类来说,也必须用这种方法来初始化基类对象。
14. 避免不合理的类赋值的技巧:把拷贝构造函数&赋值符号重载函数定义为私有,内容为空。
15. 头文件在编译时候被直接copy到cpp中,所以不需要结构定义的include;
16. 继承中指明函数为virtual时候,virtual只在.h中出现,cpp中不要;
17. 模板的格式:
stack.h:(模板的定义内容也都放在.h中)
template <class T>
class Stack {
......
};
template <class T>
Stack<T>::Stack()
{
}
......
usestack.cpp:
int main()
{
Stack<int> st;
}
18. 异常的格式:
double hmean()[throw(const char *, double)] //[]是可有可无的,throw中包括的指出该函数引发哪些会交给throw处理的类型异常(没包括在内的类型异常直接abort()处理掉)。
{
......
if(...)
throw "hello"; //throw会终止函数的执行,但不是将控制权返回给调用程序,而是沿程序调用序列一直后退到找到包含try块的函数为止。
// throw; --如果这里这么使用,那么会把控制权传递给上上层的try块。
......
return ...;
}
int main()
{
......
try {
z = hmean();
}
catch(const char *s)//catch(...)表明捕获所有的异常
{
if(s == "...")
......
}
catch(exception &ex) // 可以分多个catch应对多种情况;exception是已经提供的异常处理类
{
......x
}
......
}
事实上,常用的做法是:定义一个异常类,当遇到问题时catch-throw一个类对象,例如:
if(..)
{
classA a();
throw a;
}
...
int main()
{
...
catch(classA &a)
{ ... }
}
19. RTTI的3个元素是:dynamic_cast, typeid, type_info。
20. 4个更安全的类型转换关键字:dynamic_cast, static_cast, const_cast和reinterpret_cast。
常见错误:
1. constructors not allowed a return type 的错误:
class后面忘了加分号-_-!
2. 函数有默认值时候只能在声明中有,不能在定义中有;
3. 变量命名时候不要以数字开头;
4. 类继承时候成员初始化列表是写在.cpp中的;