C++面向对象 - 预备知识
C++程序的内存空间
- 代码区:程序代码,常量和常量字符串,相当于汇编的.text段
- 栈区(runtime):自动变量(局部变量)和形式参数,不可控,容量有限,先进先出,超出作用域自动释放;
- 堆区(runtime):复杂的数据结构以及手动分配内存(如malloc和new),需要手动释放;
- 全局区:静态数据(局部static变量,全局static变量)、全局变量。相当于汇编的.data和.bss段
头文件
-
分清C++中的定义和声明
- 简而言之,区别在于是否实际分配内存空间
- 对于基本类型的变量,声明即定义,定义即声明
- 对于类、struct和函数则不然
-
“一次定义”,但允许多次声明;分别编译,链接时实现互相调用
-
头文件
*.h
中只存放:- 函数声明:
void func(...); //不能带有大括号,那代表定义
- 变量声明:
extern int a; const int a=5; static int a=5; //const和static意味着变量作用域仅限包含它的文件内,不会造成链接时的冲突
- 类的定义,包括成员变量的定义和成员函数的声明,成员函数的定义可以写在类结构内,作为内联函数;
- 头文件内不能使用
using
语句
- 函数声明:
-
预处理命令:
#ifdef
ifndef
#undef
#endif
的用法:为了防止在头文件相互引用中出现多次定义 -
extern关键字与混合编程
-
extern
修饰普通变量或函数:告知编译器此变量/函数定义在其它文件中,要到别处寻找定义; -
extern "C"
: 混合编程,在C++中以C的方式处理C定义的函数或代码段1
2
3
4
5
6
7
8
9
10
11
12
13
14//fun.c
void func() {
...
}
...
//fun.h
extern "C" void func(); //如果引用头文件的是*.cpp,则使用带extern "C"的函数声明
void func(); //如果引用头文件的是*.c,则使用原始由c定义的函数声明
//也可以使用extern "C" {...} 对多行代码进行类似操作
-
-
C++的标准库函数即是由一系列头文件所定义的,具体包含的所有头文件可见这里
宏定义
控制宏
- 参见上文预处理命令(条件编译)
常量宏
- 显而易见,不言自明
函数宏
- 基本形式:
#define MAX(a,b) (a>b?a:b)
- 核心是字符替换
- 一些特殊情况
- 如果宏标识符出现在引号中则不会被替换
- 不加括号导致运算顺序出现问题
- #和##在带参宏中的用法:加引号和衔接
- C++中预定义的四个宏:
__LINE__, __FILE__, __DATE__, __TIME__
A Better C
此部分对应教材第7章
函数重载 Overloading
- 参数列表不同的同名函数,编译时会生成不同的内部名,对于类成员和全局的同名函数也是如此
- 不可以使用返回值重载
默认参数和占位符
-
如:
void func(int a, int b=1) {...}
-
默认参数必须放在参数列表的后部;一旦开始使用默认参数,后面的参数必须都是默认的
1
2
3
4
5
6
7
8void func(int a, int b=1, int c=2) {
cout << "Finish" << endl;
}
int main(void) {
func(1, , 3); //错
func(1, c=3); //错
} -
参数不一定需要标识符, 如:
void func(int a, int)
,第二个参数被称为占位符placeholder- 调用时需要给一个值
- “高瞻远瞩”,给之后的修改留下空间(只需改定义而无需改调用;不想用可以直接在定义处去掉名字)
从Struct到Class
主要在于未声明访问标识符时,struct默认公有,class默认私有。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Sumsky's Blog!
评论