C++ generic
关于C++头文件的路径
#include <a.h> 与 #include "a.h" 的区别
使用尖括号< >
,编译器会到系统路径下查找头文件;
而使用双引号" "
,编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找。也就是说,使用双引号比使用尖括号多了一个查找路径,它的功能更为强大,我们完全可以使用双引号来包含标准头文件,例如:
#include "stdio.h"
#include "stdlib.h"
不同的系统不同的编译器都会有自己的一套默认的放头文件的地方,比如Linux的”/usr/inclede/”就是专门用来放头文件的。
Windows下没有一个统一的放头文件的地方,安装不同的编译器会有不同的默认放头文件的地方。
我们也可以自己任意指定目录放偷吻加,以 Windows 为例,在 D 盘下创建一个自定义的文件夹,名字为abc
,它里面有一个头文件叫做xyz.h
,那么在程序开头使用#include "D:\\abc\xyz.h"
就能够引入该头文件。
为了增强代码的可移植性,引入头文件时请尽量使用正斜杠/
。
#include "./xyz.h"
语句就可以引入 xyz.h,其中./
表示当前目录(Windows下)
语句#include "./../xyz.h"
,其中../
表示上级目录。./../xyz.h
的意思是,在当前目录的上级目录中查找 xyz.h 文件。需要注意的是,我们可以将./
省略,此时默认从当前目录开始查找。(Linux下,需要使用 #include "./../module.h" ,开头的 ./ 不能省略)
建议大家使用相对路径,这样即使后来改变了工程所在目录,也无需修改包含语句,因为源文件的相对位置没有改变。
关于头文件的内容
#include 语句做了啥
把include的文件的内容插入到include语句位置
*.h文件头文件中只放声明(Declaration)不放定义(Definition)
*.h文件是用来做声明(Declaration)的,不要把定义(Definition)放在里面。
声明包括
- extern 变量
- 函数原型(不带函数体)
- 类与结构体声明(类与结构体只有声明没有定义的说法)
*.h文件只放声明,不放定义,是位了避免多个cpp文件include同一个*.h的时候link遇到重复定义(link在多个cpp文件中找到了同一个量的定义),即避免发生多个cpp文件中定义了同一个量的问题。
标准头文件结构
#ifndef _MY_H_
#def _MY_H_
……
#endif
如上位标准头文件结构,字面意思是如果没有定义宏_MY_H_,则定义_MY_H_,并执行 …… 处的代码,如果_MY_H_定义过了则啥都不干直接跳到#endif处。
如果没有这样的宏定义假设b.h里面include了a.h,b.cpp 同时 include a.h和b.h的时候就会导致a.h的内容在b.cpp中重复插入。
这种做法是为了避免在同一个cpp文件中include同一个头文件多次,导致该头文件中类的声明在该cpp文件中重复出现。
Tips:
- 每一个类的声明放在一个单独的*.h文件中,对应的源代码放在同名的*.cpp文件中。
- 头文件用标准头文件结构
- 文件名用类名命名
- 千万不要include一个.cpp文件
关于extern
函数的声明extern关键词是可有可无的,因为函数本身不加修饰的话就是extern。但是引用的时候一样需要声明的。
https://blog.csdn.net/qq_38880380/article/details/81474580
https://blog.csdn.net/CSDNwei/article/details/51836182
?????????????????????????????????
extern 与extern C的区别????
构造函数与析构函数
什么时候构造函数会被执行
构造函数即对类进行初始化的函数,在类实例化的时候会被调用。
myClass* mcls1 = new myClass(); myClass* mcls2; myClass mcls3; myClass& mcls4 = mcls3; myClass mcls5[5];
myClass* mcls1 = new myClass();
使用new 明确指定一个构造函数实例化
myClass* mcls2;
这里只是定义了一个myClass类型指针,构造函数不会被调用
myClass mcls3;
定义了一个myClass类型变量,并调用了默认构造函数,如果没有默认构造函数,编译会报错
myClass& mcls4 = mcls3;
定义了一个myClas类型引用变量,构造函数不会被调用,但是定义引用变量的时候必须同时明确给其赋值,否则会报错reference variable require a initializer
myClass mcls5[5];
定义了一个5元素的myClass变量,默认构造函数会被调用5次,如果没有默认构造函数,编译会报错