【问题标题】:Why do we declare and define functions separately in C++? [duplicate]为什么我们在 C++ 中分别声明和定义函数? [复制]
【发布时间】:2020-01-14 06:34:11
【问题描述】:

刚开始学C++,看到函数通常是分开声明和定义的,例如:

// Declaration
void sayhi(std::string name);

// Definition
void sayhi(std::string name) {
  std::cout << "Hello, " << name;
}

我尝试查找,但大多数问题都是针对 Class 的案例,但我的问题是更笼统的,为什么我们将它们分开?有什么好处?

【问题讨论】:

  • 它曾经在最初使用 C 的古代计算机上是必需的。在新的编程语言中没有充分的理由。

标签: c++ function declaration definition one-definition-rule


【解决方案1】:

同一个函数可以在不同的编译单元中使用。

如果它将在标头中定义,并且它不是内联函数或具有内部链接的函数,则如果标头包含在多个编译单元中,则单一定义规则 (ODR) 将被破坏。

因此,通常此类函数在标头中声明,但在某些模块中定义。所以使用头文件不同的编译单元会看到函数声明并且函数只会被定义一次。

如果一个程序仅由一个编译单元组成,则无需单独声明和定义函数,因为函数定义同时也是它的声明。

【讨论】:

  • 感谢您抽出宝贵时间发表评论。我需要更多的经验来理解这一切,但我非常感谢您的时间和帮助。
【解决方案2】:

我们为什么要把它们分开?

我们没有。
只要我们至少可以摆脱它,因为它违反了DRY,引入(仅部分检查)重复。

问题在于,C 来自一长串的单遍编译器,虽然 C++ 用模板和返回类型推导做了很多事情,但它并没有完全扭转这一事实。

因此,如果您想在定义之前使用函数,则必须提供前向声明。

如果您想对部分代码使用单独的编译,这通常有助于缩短编译时间并能够使用其他语言的库(静态或非静态),无需源代码,或使用其他选项编译,您需要一些方法来告诉编译器将会有什么。

头文件是这些前向声明、常量声明、内联函数(内联函数必须在每个使用它们的翻译单元中定义)、类型定义等的集合。
通常,实现文件首先包含相应的 hesder,以验证它们是否工作并且是自包含的。

诚然,C++20 引入的模块系统是一个新的转折点,进一步减少了对前向声明的需求。

【讨论】:

  • 这很有帮助。我肯定需要更多的经验才能完全理解你的解释,但我感谢你的赞扬。谢谢。
  • 直截了当...我们通常不会将函数声明和定义分开,因为它使脚本变得冗长,除非程序是 WIP,因为它仍处于开发阶段??
  • @NaderBelal 只要没有必要,将声明与定义分开只是开销。 WIP 与此无关。
  • 什么时候需要??
  • @NaderBelal 相互递归和标头。
【解决方案3】:

头文件是从多个翻译单元访问变量声明和函数原型的便捷机制。

#include <header> 

允许您将这些包含在许多类中。从而使代码更具可重用性。

【讨论】:

  • 你可以在没有分离声明和定义的头文件中实现所有内容。我相信这个答案不能回答问题。
  • 什么意思?
  • 他问他们为什么分开,我相信这回答了问题
  • 如果您想补充 Morpheus 的答案,this question 的最佳答案的要点对于函数和类一样有效。
  • 您的回答谈到了将代码与可以包含的头文件分离。这与声明和定义的分离无关,例如.hpp.cpp 文件。正如我所说 - 可以将一些代码移动到头文件(就像你在回答中所说的那样)并且仍然没有将声明和定义分开,这似乎是问题的本质。
猜你喜欢
  • 2021-07-13
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 2013-02-03
  • 2014-11-26
  • 1970-01-01
相关资源
最近更新 更多