头文件(.h)和实现文件(.cpp)分别写什么:
非模板(non-template) | 模板(template) | |
头文件(.h) | 全局变量的声明 (带extern限定符) | 全局模板函数的声明和定义 (带inline限定符) |
全局函数的声明 | ||
全局函数的定义 (带inline限定符) | ||
类的定义 | 模板类的定义 | |
类函数成员和数据成员的声明 (在类内部) | 模板类成员的声明和定义(定义可以放在类内部或者外部,外部不需要写inline) | |
类定义内部的函数定义 (相当于inline) | ||
类定义外部的函数定义 (带inline限定符) | ||
类内部数据成员的初始化 (带static const限定符) | ||
实现文件(.cpp) | 全局函数的定义(及初始化) | 无 |
全局函数的定义 | ||
类函数成员的定义 | ||
类数据成员的初始化 (带static限定符) |
头文件的内容书写格式:
#ifndef {filename}
#define {filename}
// {content of head file}
#endif
这样书写头文件的作用:
保证头文件在被
多个其他文件引用(include)的时候,内部的数据
不会被多次定义而造成错误;
inline函数
(1)目的:
a.提高代码的运行效率
b.提高代码的可读性
(2)对象:使用频率较高的小段代码
(3)实现:编译系统为inline函数创建一段代码,每次调用inline函数的时候用该段代码替换
(4)限制:非循环,非递归,小段代码,编译系统控制
解释:
(1)
|
|
可以通过inline函数来弥补这两个缺陷
#include <iostream>
inline int isnumber(char); int main(){ char c; while((c=cin.get())!='\n'){ if(isnumber(c)){ cout << "you enter a digit." } else{ cout << "you enter a non-digit." } } return 0; } int isnumber(char ch){ return (ch > '0' && ch < '9')?1:0;
}
|
#include <iostream> int isnumber(char); int main(){ char c; while((c=cin.get())!='\n'){ if(isnumber(c)){ cout << "you enter a digit." } else{ cout << "you enter a non-digit." } } return 0; } inline int isnumber(char ch){ return (ch > '0' && ch < '9')?1:0; } |
正确的inline:在函数声明处。 编译器在看到inline的时候,为isnumber函数创建一段代码(即表达式 (ch > '0' && ch < '9')?1:0),以后每次调用该函数的时候就会用这段 代码替换isnumber函数, 这样的话,既可以提高代码的运行效率, 又可以提高代码的可读性 | 错误的inline:在函数定义处 |
inline函数弥补宏定义的缺陷:
宏定义 | inline函数 |
#define MAX(a,b) ((a)>(b))?a:b 这里没有规定a,b的类型,即说明宏定义没有类型检查 | inline int max(int a, int b){ return a>b?a:b; } |
int a=1; int b=0; MAX(a++,b); //返回3,a=3----a++执行了两次 MAX(a++,b+10); //返回11,a=2----a++执行了一次 MAX(a,"hello"); //错误地比较int和字符串,没有参数类型检查,可通过编译(危险!!) //因为宏定义的时候没有规定a,b为int类型 | |
程序结构中的外部存储类型:extern
我们平时所写的C++程序可能很多都是只有一个文件(单个.cpp),当我们编写复杂的程序的时候,就需要用到多个文件,那么我们就有必要协调各个文件之间函数和变量的声明和初始化,从而避免函数和变量的多次定义,冲突定义和未定义。
看下面的程序:
******file.prj****** file1.cpp file2.cpp | 工程文件中包含两个.cpp实现文件file1.cpp和file2.cpp |
******file1.cpp****** #include <iostream> using namespace std; (extern) void fn1(); (extern) void fn2(); int n; void main (){ int n=3; fn1(); cout << n << endl; } void fn1(){ fn2(); } | file1.cpp文件中 fn1在file1.cpp中定义,fn2在file2.cpp中定义 首先声明全局变量n,没有初始化 |
******file2.cpp****** extern int n; void fn2(){ n=8; } | 带extern的变量声明说明这个变量n由其他地方来定义,该变量n不在本文件file2.cpp中分配空间。 即是说,在文件file1.cpp中有一块空间分配给n,在file2.cpp没有分配。 |
******file1.cpp****** int a=5; int b=6; extern int c; | 文件file1.cpp中分配内存空间给a,b,没有分配给c,因为c是由外部定义(带extern修饰符) |
******file2.cpp****** int a; extern double b; extern int c; | 文件file2.cpp中分配内存空间给a,没有分配给b,c,因为b,c都是由外部定义(带extern修饰符) error,多次定义 error,冲突定义----b带extern限定符说明由其他地方来定义(这里由file1.cpp),但是file1.cpp定义的是int类型, error,无定义----file1.cpp和file2.cpp中的c都是extern的,他们都希望其他地方来定义,但是该程序所有文件(只有file1,file2)都没有定义,那么产生了变量无定义的情况。 |