C++学习 十二、内存模型,作用域,名称空间 (1)多文件编译

C++学习 十二、内存模型,作用域,名称空间 (1)多文件编译

前言

本篇继续C++学习总结。

本篇将探讨C++中,变量与函数的内存模型,以及在多文件程序中的关系。先从多文件编译方法开始。

多文件编译

模块化

由于大型程序的编译非常耗时,将所有代码写在一个源文件里是不现实的。通常做法是,把结构,类,符号常量等声明放在一个文件中,把具有相同功能的函数放在另一个文件中,把实际运行的程序单独放在一个文件中,形成不同的模块。

文件结构

一般把C++程序分为三部分:头文件,源文件,程序入口文件。

头文件.h

头文件包含内容:

  • 函数声明
  • #define宏定义
  • const符号常量
  • 结构声明(定义)
  • 类声明(定义)
  • 函数模板声明(定义)
  • 内联函数定义

函数定义和变量声明不能放在头文件中,否则如果另外两个头文件包含了该头文件,程序入口包含这两个头文件,就会报redefined的错误。

内联函数与const变量是例外,也应当放在头文件中。

其它文件如果需要头文件里的函数、结构、类等声明,则可以直接通过#include头文件来使用。

注意:实际操作中,结构和类定义也会一并放在头文件中,这也可能造成上述redefined问题;函数模板的声明与定义也会放在头文件中,否则容易出现模板篇中提到的undefined reference问题,但这也可能造成redefined问题。

注意#include <xxx.h>将在标准头文件目录下查找;#include "xxx.h"首先在当前工作目录下查找,如果没有找到.h文件,再到标准目录下查找。

在一个文件中,只能将同一个头文件包含一次,否则很容易出现上面的redefined问题。要解决该问题,首先要知道文件编译中#include "xxx.h"干了什么。

#include:预编译器接收#include指令,把#include "xxx.h"替换为xxx.h文件中的内容。

因此,如果包含同一头文件两次,而头文件又刚好具有结构、类、函数模板的定义,就报redefined错误。

头文件结构

为了防止重定义,可以通过下面示例的头文件结构来避免:

// example.h
#ifndef EXAMPLE_H_
#defined EXAMPLE_H_

struct myStruct{
	int a;
	float b;
	bool c;
};

void func1(int a);

int func2();

#endif

如果引用该example.h的源文件之前没有宏定义EXAMPLE_H_,则宏定义EXAMPLE_H_,并进行结构定义和函数声明等操作。之后再重复包含example.h时,EXAMPLE_H_已被宏定义,就不会重复包含头文件的内容。

此外,头文件包含还有一些比较常见的约定:

  • 尽量不在头文件中包含其它的头文件,特别是自定义头文件。
  • 尽量在同名源文件中包含其它的头文件,而不是在同名头文件中包含。

源文件.cpp

普通源文件示例:

#include "example.h"

void func1(int a){
	a = 1;
}

int func2(){
	return 1;
}

普通源文件主要是定义同名头文件中声明的函数。

程序入口文件示例:

#include "example.h"

void main(){
	func1(0);
	func2();
}

程序入口文件必须要包含使调用函数的头文件,否则报error: xxx was not declared错误。

编译只编译.cpp文件。首先预编译把每个.cpp文件的头文件替换,注释删去,宏定义替换,条件编译;然后把每个.cpp文件编译成汇编码文件,再汇编成机器码文件,最后链接。

后记

下篇继续记录C++的内存模型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值