C++ 学习笔记三

1.文件和流

2.C++动态内存分配

  • 栈:在函数内部声明的所有变量都将占用栈内存。
  • 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

    在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。如果您不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存、

 malloc() 函数在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量不要使用 malloc() 函数。new 与 malloc() 函数相比,其主要的优点是,new 不只是分配了内存,它还创建了对象。在任何时候,当您觉得某个已经动态分配内存的变量不再需要使用时,您可以使用 delete 操作符释放它所占用的内存。

double* pvalue = NULL; // 初始化为 null 的指针

pvalue = new double; // 为变量请求内存

delete pvalue; // 释放内存

char* pvalue  = NULL;   // 初始化为 null 的指针
pvalue  = new char[20]; // 为变量请求内存
delete [] pvalue;        // 删除 pvalue 所指向的数组

对象的动态内存分配

Box* myBoxArray = new Box[4];

delete [] myBoxArray; // 删除数组

delete 与 delete[] 区别:

针对简单类型 使用 new 分配后的不管是数组还是非数组形式内存空间用两种方式均可 如:

int *a = new int[10];   
delete a;   
delete [] a; 

针对类Class,两种方式体现出具体差异

// 仅释放了a指针指向的全部内存空间 但是只调用了a[0]对象的析构函数 剩下的从a[1]到a[9]这9个用户自行分配的m_cBuffer对应内存空间将不能释放 从而造成内存泄漏
delete a;
// 调用使用类对象的析构函数释放用户自己分配内存空间并且   释放了a指针指向的全部内存空间
delete [] a;

对于像 int/char/long/int*/struct 等等简单数据类型,由于对象没有 destructor,所以用 delete 和 delete [] 是一样的!但是如果是C++ 对象数组就不同了!

new 和 malloc 内部的实现方式有什么区别?

new 的功能是在堆区新建一个对象,并返回该对象的指针。

所谓的【新建对象】的意思就是,将调用该类的构造函数,因为如果不构造的话,就不能称之为一个对象。

而 malloc 只是机械的分配一块内存,如果用 mallco 在堆区创建一个对象的话,是不会调用构造函数的。

严格说来用 malloc 不能算是新建了一个对象,只能说是分配了一块与该类对象匹配的内存而已,然后强行把它解释为【这是一个对象】,按这个逻辑来,也不存在构造函数什么事。

同样的,用 delete 去释放一个堆区的对象,会调用该对象的析构函数。

用 free 去释放一个堆区的对象,不会调用该对象的析构函数。

3.C++ 命名空间

4.C++ 预处理器

预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。

所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾。

#define 预处理指令用于创建符号常量。该符号常量通常称为,指令的一般形式是:  #define PI 3.14159

参数宏:使用 #define 来定义一个带有参数的宏,如下所示:#define MIN(a,b) (a<b ? a : b)

条件编译

有几个指令可以用来有选择地对部分程序源代码进行编译。这个过程被称为条件编译。

条件预处理器的结构与 if 选择结构很像。请看下面这段预处理器的代码:

#ifdef NULL
   #define NULL 0
#endif
#ifdef DEBUG
   cerr <<"Variable x = " << x << endl;
#endif
#if 0
   不进行编译的代码
#endif

4.C++信号处理;

信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。

有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中。

// 注册信号 SIGINT 和信号处理程序

signal(SIGINT, signalHandler);

用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:
int raise (signal sig);在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP

6.C++多线程

多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程

  • 基于进程的多任务处理是程序的并发执行。
  • 基于线程的多任务处理是同一程序的片段的并发执行。

多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径。

猜你喜欢

转载自blog.csdn.net/weixin_42627035/article/details/85604503