c++ primer plus阅读笔记(三)

来源:互联网 发布:鼠标手势软件 编辑:程序博客网 时间:2024/06/05 01:15

头文件的写法

source2.h-------------------------------------#ifndef#define SOURCE_2_H_extern int a;   #endif-------------------------------------source2.cpp-------------------------------------#include"source2.h"...int a=5;-------------------------------------

#ifndef的作用

程序运行的时候,include的头文件的所有内容会被替换到目标文件下,替换完毕之后,一个完整的cpp是一个单独的编译单元,此时有可能出现一个头文件被多次引入的情况,比如说在main.cpp中引入了头文件A,而main.cpp下引入的头文件B中又引入了头文件A,此时的完整替换完的main.cpp文件就会有多段重复的代码,这是采用宏就可以不对编译过的代码再次编译。
但要注意的是,#ifndef可以对重复的代码不进行二次编译,所以main.cpp单元内就不会出现重复定义这个问题,但是到了链接阶段,多个cpp可能同时引入了头文件A,所以把变量的定义或者函数的定义放在头文件中会导致链接阶段重复定义的问题,考虑到这点之后,c++推出了关键字extern用在表示声明变量是外部链接过来的,也叫引用声明,表示当前变量的定义只是一个声明而不是一个定义,所以extern必须用在是外部链接的变量上,具体的定义需要在链接的过程中找到对应文件下的定义。如上述source2头文件的例子,extern int a表明这只是一个变量的声明,并不是在此处定义的,在链接阶段会从对应的.cpp编译的二进制文件中找到变量。所以在头文件中一般只写声明。
extern这个关键字本身有很多细节,使用该关键字时如果初始化的话,就会创建变量而不是一个引用声明,全局变量不是static的话,默认是extern,可以省略等。
头文件中的const类型是可以不需要添加extern的,因为和static一样是内部链接,所以不会出现在链接阶段重复定义的问题。
总的来说,define是用来处理独立编译单元的时候不包含模块的方法,而extern则是处理链接的时候编译单元之间的不出现重复模块的方法。

一些内部引用的类型

const类型和static类型都为内部链接的,只在当前的编译单元有效。

定位new运算符

//使用new去分配指定的内存int a[20];int * temp=new (a) int[20];//从数组a的空间中分出一个 int [20]的数组//定位new的好处是可以在频繁需要申请或删除堆内存的时候提高效率//需要注意的地方时//1.定位new没有对应的delete操作,因为它本质也不是申请了一块内存而只是使用//2.它的原型是 new (mem_address+offset) type [size],offset没有设定好,可能导致多个变量使用重叠的内存。

::作用域解析符

空间名称::空间下的变量如果::前面没有东西的话,就代表是全局变量

using

using声明,就好像将变量放在当前域

namespace jack{    int a=5;}int main(){    using jack::a;//在main中引入jack的a变量}

using编译指令,将变量放在当前域的全局域中

namespace jack{    int a=5;}int main(){    using namespace jack;//在main中引入jack的a变量    cout<<a<<endl;}

有了using 为什么还需要使用include?

编译的过程是首先将include文件的内容替换到当前的文件中的,名称空间的定义是来自于include的代码,然后下面才能using 名称空间。

多条using

多条using编译指令一起使用的时候,结果是对当前所在域添加了一个额外的全局变量空间,其中的变量是名称空间变量的交集,但是重复的变量有二义性无法使用。