c++面试:类定义为什么可以放到头文件中

这个问题是刚了解预编译的时候产生的疑惑。

  1. 声明是指向编译器告知某个变量、函数或类的存在及其类型,但并不分配实际的存储空间。声明的主要目的是让编译器知道如何解析程序中的符号引用。
  2. 定义不仅告诉编译器实体的存在,还会为该实体分配存储空间(对于变量)或者提供具体的实现(对于函数)。定义只能出现一次,以避免重复定义错误。
  3. 类定义描述了一个类型(或称“蓝图”),它定义了该类型的成员变量、成员函数以及其他特性。类定义本身并不分配内存,它只是提供了创建对象的模板。【很明显与函数定义和变量定义很不相同】对象定义则是基于某个类创建的具体实例,它会在内存中分配空间。
  4. 编译器将类中声明的函数视为内联函数。当你在类定义内部定义成员函数时(即直接在类体内部提供函数体),这些函数默认为是inline的,如果使用 inline ,则意味着编译器会在调用此函数的地方把函数的目标代码直接插入,而不是放置一个真正的函数调用,实际作用就是这个函数事实上已经不再存在,而是像宏一样被就地展开了,因此不存在重复定义的问题。

总而言之,类定义其实只是描述了一个类型,并不会分配具体的空间,在类内实现的函数编译器认为是inline,调用时会展开成具体的代码,所以不存在重复定义。因此类定义可以放到头文件中被不同的源文件引用也不会产生重复定义的问题。

两次导入头文件

预编译指令是以井号(#)开头的指令,它们在编译器进行编译之前执行。预编译指令不是C++语句,因此它们不以分号(;)结尾。预编译指令包括但不限于以下几种:

  • #include:用于包含头文件,将头文件的内容插入到源文件中。系统提供的头文件使用尖括号<>括起来,而用户自定义的头文件使用双引号""括起来。
  • #define:用于定义宏,宏可以是简单的符号常量或带参数的宏。宏定义在预处理阶段会被替换成相应的文本。
  • #if、#ifdef、#ifndef、#else、#elif、#endif:这些条件编译指令用于根据条件判断是否编译某部分代码。
// add.h
int add(int, int);
class Person{
   
public:
	int age;
}

// add.cpp
#include "add.h"
#include "add.h"
int add(int a, int b) {
   
	return a + b;
}

我们使用g++ -E add.cpp -o add.i的命令可以得到预编译后的文件

// 遇见#include "add.h",将add.h中的内容展开

// 第一次执行#include "add.h"展开成如下内容
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值