c++中前置声明和#include

c++中前置声明和#include

  • 能用前置声明的尽量用前置声明,尽可能的避免用#include头文件
  • 尽量在cpp文件中包含头文件,而非在头文件中
头文件相关

若.h文件和cpp文件不在解决方案里:位于其文件中,单独的引用到.h文件会报“error LNK2019:无法解析外部符号”的错误,但是单独引用.cpp文件就可以,include是吧对应的代码直接拷贝过去

当.h文件和.cpp文件没有在工程的解决方案里时,#include就是纯粹的拷贝和复制文件

源码编译过程:

远程序->预处理->编译和优化->生成目标文件->链接->可执行文件

  • 预处理(简单替换)
    • 宏替换
    • 删除注释
    • 处理预处理指令,#include #ifdef等
  • 编译和优化(高级语言->汇编语言)
    • 词法分析、语法分析、语义分析、代码优化、代码生成
    • 内联函数的替换就在该过程中
    • 编译单元:一个cpp文件就是一个编译单元,相互独立
  • 生成目标文件(汇编语言->二进制文件)
    • 编译器最中生成的目标文件会将cpp文件的数据写入其中,会有三个表:
    • 1、为解决符号表:提供所有在该编译单元里引用但是定义并不在该编译单元的符号及其地址;
    • 2、导出符号表:提供本编译单元具有的定义,并提供给本单元和其他单元使用的符号及其地址;
    • 3、地址重定向表:提供本编译单元所有对自身地址引用的记录;
  • 链接(汇总成一个目标文件)
  • 外部文件夹的.h文件和.cpp文件
    外部文件的cpp文件并不能单独生成编译文件,所以不参与为解决符号表和到处符号表的生成,#include外部的.h文件只是将文件中的函数声明复制进来,并没有定义,在链接过程中会报错,可以直接#include外部的cpp文件(该方法不建议),或者头部#include 外部.h文件,在尾部#include外部.cpp文件;
前置声明与#include

.h头文件

class A
{
private:
	int a,b;
};

.cpp文件中的两种引用方法

//前置声明
class A;
class B
{
private:
	A* a;
	int c,d;
};
//第二种引用#inlude头文件
#include "A.h"
class B
{
private:
	A* a;
	int c,d;
};

这两种都能编译通过,且都没问题,但是第一种明显好与第二种;因为当A类的内容给修改后,所有#include到A.h的文件都要重新编译,但是使用前置声明的不用重新编译;
编译器编译需要知道文件的大小,所以当类B中以指针的形式引用类A时可以使用前置声明,单若时用到了类A的对象那就必须使用#include包含类A的头文件
具体情况如下:

  • B继承A,必须#include A.h,需要获得A的定义
  • B有一个指针类型为A的成员变量,前置声明就可以
  • B有一个引用类型为A的成员变量,前置声明
  • B有一个不同类型为A的成员变量,需要使用#iclude A.h
  • B用使用到标准模板库,例如vector< A >,前置声明九月可以,标准模板库内部使用的是指针作为成员变量
  • B中有函数成员函数返回类型和参数为A的,前置声明
  • B中有函数成员函数返回类型和参数为A的,并且在头文件中定义此函数并调用A中的成员或函数,需要#iclude A.h

使用对象引用(object reference)或对象指针(object point)能解决的不要使用对象(object)

c++中接口与实现分离最重要的就是降低文件之间的编译依赖关系和异常对象的实现细节,实现手段关键就是”Pimpl模式(pointer to implementation)“,即把一个类的实现细节代理给另外一个类来完成,自己只提供负责接口,也就是以来对象的声明,而非定义;

  • 对象循环依赖
//头文件A
#include "B.h"
class A
{
private:
	B b;
};
//头文件B
class A;
class B
{
private:
	A* a;
};

使用前置声明可解决相互依赖头文件相互依赖问题
前置声明的作用
1、解决class相互依赖问题
2、降低文件之间的编译依赖关系
3、前置声明可以实现接口与实现分离,提供给客户的类分为两个class,一个用来提供接口,一个负责实现;
https://blog.csdn.net/u011913417/article/details/100183653
https://www.cnblogs.com/rednodel/p/5000602.html

你可能感兴趣的:(c++基础,linux,c++,编译器)