联合及枚举、特殊指针、流


基础

前四章属于基础中的基础,基本上没有什么新的收获。只总结两个以前见得比较少的类型。

联合union

这个东西在书里叫做共用体,而我已经习惯了把它叫做联合,尽管“共用体”这个名称实际上更加准确。

联合相当于一个可变类型的变量,根据需要给它赋予不同的值。我个人觉得这个功能似乎有点鸡肋,变 类型的情况好像不是很常见。我遇到的可以用联合处理的问题大概也就是中英文字符串混用吧?比如需要 读取一些名字,有英文名也有非英文名,像中文、日文、韩文、阿拉伯语这些文字。于是联合声明一种Name类 型:

union Name{
	string english;
	wstring others;
};

这样就可以同时处理各种不同编码的语言(虽然现在大家都倾向于UTF-8一把梭www)。

枚举enum

这种类型是比较常用的,无论是用C++写成的Qt库,还是C语言写成的libcurl,都有用到这种类型。 枚举的功能类似 C++ STL 里面的map,也就是映射,但是比较单一。它可以把一些标识符映射成 对应的数字常量。例如,在 libcurl 项目的 curl.h 中有如下定义:

typedef enum {
  CURLE_OK = 0,
  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
  CURLE_FAILED_INIT,             /* 2 */
  CURLE_URL_MALFORMAT,           /* 3 */
  CURLE_NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
                                    7.17.0, reused in April 2011 for 7.21.5] */
  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
  ......
}CURLcode;

在这一块代码中,定义了错误码类型CURLcode,通过把标识符映射为错误码的方式,给各种错误定义了 对应的错误码,并且和变量不同,它们是常量。如CURLcode::CURLE_OK等价于常数0。

注意到,这里显式地声明第一个标识符映射到0,于是默认地,后面的标识符映射到的数字依次 加一。如果不作此声明,默认仍然会从0开始。

智能指针

C++最大的特点之一是开发者可以直接通过指针操作内存,然而这一特性由于经常引发内存泄漏、段 错误等严重问题,也久为人所诟病。因此STL提供了智能指针,可以缓解内存泄漏的问题, 但还是无法解决某些段错误。

智能指针包括unique_ptrshared_ptr等。由于我认为它们比较鸡肋,因此不过多总结(绝对不是 想要偷懒)

缓冲区溢出

文件的读写操作基本上很熟悉了,本来觉得没啥好总结的,但是“缓冲区”这个眼熟的词引起了 我的注意。

缓冲区是为了减少磁盘读写次数而设置的一段内存空间。通过C++的某些函数写文件时,程序输出的 少量数据会暂存在缓冲区,直到达到合适的大小后一次性写入磁盘。读取也类似,只不过流程相反。

过去曾经见过的“缓冲区溢出攻击”就是利用了缓冲区。其原理是:如果程序没有检查输入到缓冲区的 数据大小,就可能导致输入的数据大于缓冲区容量,从而导致某些数据会溢出缓冲区,覆盖掉原本的 数据或者代码。因此可以构造足够大而且包含恶意代码的数据输入含有漏洞的程序,使正常的程序运 行恶意代码。(应该是)由于这个原因,诸多C++经典教程中教的如scanf()gets() 这样不检查输入大小的函数在MSVC中已经被默认禁用。

参考

Cloudflare

维基百科


文章作者: LouisZ
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LouisZ !
  目录