- 在C++中要使用头文件,最主要的原因是C++同一个项目可能包含多个源代码文件,这些源代码文件分别单独编译,也就是说在编译其中一个文件时,编译器并不知道其它文件中定义的内容,如类全局变量等,所以要求我们在要使用某个类,函数或者变量的每个文件中声明它,否则C++无法找到它
- 头文件为所有extern对象声明,模板类定义,常量,函数声明以及Inline函数定义和模板函数定义提供了一个集中的位置,这意味着符号常量和inline函数可以被定义多次。头文件提供了两个安全保证:
- 保证所有文件都包含同一个全局对象或函数的同一份声明
- 如果需要修改声明,只需要修改一个头文件
- 头文件不能包含非inline函数或对象的定义
- 内联函数必须在调用它的每个文件中被定义,否则会导致编译失败. 在类定义中定义的函数默认都是内联函数,所以一两行以上的函数最好被定义在类体外,可以跟类体在一个头文件中.默认类体外定义的函数如果未使用inline修饰都不是内联函数.
- 为防止头文件重复包含,一般在头文件中使用预编译指令#define,#ifndef,#endif来书写头文件内容
- 除了整形的静态常量数据成员外,数据成员不能在类体中被显示的初始化。整形静态常量数据成员即使在类体内初始化了也应该在类外重新定义,只是不能指定初始值.如果类内未初始化,则要在类外初始化
- 一般地,静态成员应该在类体外初始化,与全局对象一样静态数据成员也只能定义一次,所以不应该放在头文件中.
- 静态成员函数不能声明为const或volatile,在类体中声明时要加static关键字,在类体外定义时不能加static
- 对同一内存区域执行两次delete运行时会抛错,一般在执行第一次delete后把指针赋值为NULL,再执行delete就不会出错.
- 动态分配的数组的第一维不必是常量,如char *str = new char[dimension];dimension是个变量
- 函数指针不能被赋值为成员函数的地址,即使返回类型和参数表完全匹配.定义一个类成员函数指针需要制定返回类型,参数和类,且类成员函数的指针总是通过特定的对象或者指向该类型对象的指针来访问,如:
int (Screen:: *ptr)(int,int)=&Screen::add;
Screen screen;
(screen.*ptr)(x,y)
Screen *ptrScreen=new Screen()
(ptrScreen->*ptr)(x,y)
typedef int Screen::*PS_Screen;
PS_Screen ptrAdd= &Screen::add;
Screen myScreen;
myScreen.*ptrAdd(x,y)
- 类的静态成员函数指针与普通函数指针一样,调用时不需要类对象
- ::是域操作符,单独使用时表示全局作用域
- volatile可以阻止编译器对其修饰的变量的优化
- 使用using引入名字空间的函数时不能带函数参数。using声明引入的函数就好像在using声明出现的地方被声明的一样
- C++的空类大小是一个字节,使用这个字节标示不同的对象,因为不同的对象地址是不同的
- 重载函数必须都在一个域中
- extern “C”链接指示符只能指定重载函数集中的一个函数,因为以extern “C”编译的两个重载函数名字会相同,导致程序不知道该调用哪个
- 参数类型是const 或者 volatile时,在识别函数声明是否相同时,不考虑const或者volatile,如果const和volatile应用在指针或引用类型的参数上,则要考虑const和volatile
//如下两个函数是重复声明,而不是重载 void f(int);
void f(const int);
- new operator与operator new的区别:
- struct所占内存大小受内存对齐的影响与struct各成员大小之和不一样,内存对其规则遵循如下两条:
- struct内每个成员的偏移量要是该成员大小的整数倍
- 整个struct的大小要是其每个成员大小的整数倍,成员是数组时,只要求struct大小是数组成员类型大小的整数倍
|