(6)第2章的尾巴~
2.6.3编写自己的头文件P67中提到:“库类型string在名为string的头文件中定义。又如,我们应该把Sales_data类定义在名为Sales_data.h的头文件中”,后面又提到:“例如,我们的Sales_data类包含有一个string成员,所以Sales_data.h必须包含string.h头文件。”
在这我有几个疑问:
1.string头文件和string.h头文件是两种类?区别?
参考:https://www.zhihu.com/question/66475735下到处挖坑蒋玉成和暮无井见铃等回答,顺便发现一个好东西,C++的中文参考手册:
照例自己总结一下:
1.查答案的Sales_data和Sales_item头文件,看看里面的代码就发现其实只引用了<string>,所以书里写错了,所有的string.h就是string才对。
2.这玩意又是历史遗留问题,和HTML5标签的"/"问题差不多.由此看来很多东西不懂的时候可以考虑考虑会不会又是历史原因。
C++ 倾向标准库头文件无后缀,而第三方库头文件使用 .h/.hpp 后缀。来自 C 的头文件都换了 cxxxx 的马甲,可能是因为写成 xxxx.h 就显得像非标准库。
(操作系统提供的库,比如<unistd.h>或者<windows.h>还是留着.h的)
3.发现了一个好网站,C和C++的参考手册,之前都不知道有这东西:
中文:http://zh.cppreference.com/w/首页
我是对照着看了,谁让我英语差呢.....(底部有切换语言的地方。)
4.几个回答的评论里有好东西,比如:
标准保证的是 xxxx.h ( C++ 版本)有和 cxxxx 同样的名称,只不过前者的在全局,后者的在 std 。但也允许前者把名字放入 std ,后者把名字放入全局。
一般实现都是 xxxx.h 兼容 C 和 C++ ,不考虑 std (但要考虑 extern "C" ),而 cxxxx 包含 xxxx.h 后再把标准规定的名称导入 std 。
2.系统定义的类是不是都不加.h,自己定义的类才加.h,以此来区分系统类和自定义类?
1. 见第一个问题里的2;
2.自定义头文件不写后缀名会被gcc编译器认为是未知文件所以你仍然需要写.h……
预处理器概述
在上一篇文章中,使用Sales_data的程序就先后两次包含了string头文件:一次直接包含的,为了能使用string类;另一次是隐式包含进来的,即Sales_data类定义时用到的那个string头文件。由于我写的时候Sales_data类是定义在主函数外面的,所以实际上只包含了一次string头文件——只有你把Sales_data类定义在另一个文件(头文件)中,才会出现开头提到的情况,那个时候你不仅要#include <string>还要include<Sales_data.h>(头文件一旦改变,相关的源文件必须重新编译才能获取更新的声明,注意是重新编译!重新编译一遍!)
基于上述描述,你会发现有必要在书写头文件时做适当处理,不然多次包含的情况很可能就不能正常和安全地工作了。
于是引入了预处理器来解决这个问题。(常用的技术,可能还有别的)
这个技术是从C语言继承过来的,她可以部分地改变我们所写的程序,之前的#inclued就是一项预处理功能(预处理器看到这个标记会用指定的头文件内容代替#include)
这里新引入的预处理器功能是头文件保护符(head guard):
//检查变量指定的预处理变量是否已经定义——当且仅当变量已定义时为真 //ifndef=if not define #ifndef SALES_DATA_H //预处理变量有两种状态,这里把一个名字设定为预处理变量 #define SALES_DATA_H #include <string> struct Sales_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; }; //结束 #endif /* *除了ifndef还有个ifdef,用法很像if else,只不过是用来预处理而已。先这样理解: *第一次包含Sales_data时,ifndef为真,继续执行define定义预处理量即头文件名,然后就会把在endif前的内容拷贝到程序 *第二次遇到时,ifndef为假,就结束了。 */ //预处理变量无视C++中关于作用域的规则
这一节的课后习题就不贴了,很简单,上面的代码写在头文件里,放在程序文件夹,引用即可。
微软自己也弄了一种机制,但是不能跨平台,所以最好还是用上面说的那种,详细可以参考文章(其中还说了头文件保护符的缺点,没看懂):
http://blog.csdn.net/zlhy_/article/details/8192580
什么是预处理变量?P68
其实到了这里,我发现在有规定的用法上,与其百度文章看或是知乎,不如直接看参考手册!那才是最正确的!很多文章都是根据自己使用的“经验”去说的,这就难免与手册所言有差别!所以,以后这种问题,只要看作者分析优缺点就够了,用法上不必太理会!