【问题标题】:Is defining functions in header files malpractice?在头文件中定义函数是否存在弊端?
【发布时间】:2022-01-21 02:56:49
【问题描述】:

我们有这个头文件: headerA.h

#pragma once
#include <iostream>

void HeaderADefinedFunction()
{
std::could << "HeaderDefinedFunction called!\n";
}

然后在sourceB.cpp里面

#include "headerA.h"
void FunctionB()
{
HeaderADefinedFunction();
}

在sourceC.cpp里面

#include "headerA.h"
void FunctionC()
{
HeaderADefinedFunction();
}

在头文件本身中定义函数 HeaderADefinedFunction() 有哪些负面影响。该定义是否是该特定函数的链接时符号解析的最佳形式?

【问题讨论】:

  • 您有兴趣了解one definition rule,以及编写不违反单一定义规则的函数的方法。
  • 同一个函数会有两个定义,所以违反了ODR;无需诊断。而且,从项目管理的角度来看,如果你改变了HeaderADefinedFunction 的实现,你必须重新编译两个源文件;如果它在它自己的源文件中,你只需要重新编译那个。
  • @DrewDormann 谢谢,这会有所帮助
  • @PeteBecker 我的错,我在浴室里用头顶打字,它是 iostream
  • void HeaderADefinedFunction() 更改为inline void HeaderADefinedFunction()inline 关键字允许您在多个翻译单元中定义函数并将它们链接在一起。

标签: c++ linker


【解决方案1】:

所示代码应该会产生一个链接失败,并带有多重定义的HeaderADefinedFunction() 符号。

使代码真正有效,函数必须是inline

在头文件中定义函数是否存在弊端?

一点也不。其实template函数必须定义在header1中。

在头文件本身中定义函数 HeaderADefinedFunction() 有哪些负面影响。

一个负面因素是,如果您更改定义,您必须重建 每个 .cpp which #includes 此标头,增加重建时间。

另一个是你的目标文件更大。

该定义是否是该特定函数的链接时符号解析的最佳形式?

如果您在标头中定义函数(并使其内联),编译器可能会选择将其内联到部分(或全部)调用站点中。无需 LTO。

如果您,编译器将无法执行此类内联,除非您使用 LTO。


1 除非您知道 template 实例化的所有类型并为所有类型提供显式实例化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2019-07-14
    相关资源
    最近更新 更多