对于在C++头文件中定义函数带来的陷阱,有点困惑

A bit confused in-regards to pitfalls that come along with defining functions in header files in C++

本文关键字:陷阱 函数 C++ 文件 定义      更新时间:2023-10-16

有人告诉我,在头文件中定义函数的唯一真正好主意的事件是函数是否标记为内联或函数模板。显然,或者我被告知,其中一个关键原因是一个定义规则 - 一个只允许每个翻译单元一个函数定义的规则。有人告诉我,对于包含该标头的每个 cpp 文件,您将获得该函数的一个定义。但是,我在理解如何为C++中的每个 cpp 文件获取该函数的一个定义时遇到了问题。我很难想象为什么会这样。那么,有人会介意提供一些见解来解释为什么会这样吗?干杯!

当您#include文件时,编译器的行为就像您刚刚将文件复制粘贴到当前文件中一样。

也就是说,如果您有三个文件:

// header.h
void foo() {/* do stuff */}
// a.c
#include "header.h"
void a_func() {/* do stuff */}
// b.c
#include "header.h"
void b_func() {/* do stuff */}

然后编译器会将其视为将header.h的内容复制到a.cb.c中 - 也就是说,它的行为与以下情况完全相同

// a.c
void foo() {/* do stuff */}
void a_func() {/* do stuff */}
// b.c
void foo() {/* do stuff */}
void b_func() {/* do stuff */}

显然,这里有多个foo定义 - 因为每个文件中都有一个。

对于简单的函数,如sum定义将是:

double sum(double a, double b) { return a + b; }

声明

double sum(double a, double b);

您将声明放在标题中,例如 sum.h,所以以后你可以使用sum的定义,例如放在sum.cpp中。稍后,链接器在对象文件中查找 sum 的定义sum.o

由于#include杂注被替换为标头的内容,因此如果将函数的定义放在标头中,则会有多个相同的函数,并且还会出现链接器错误。