【问题标题】:When to use Header files that do not declare a class but have function definitions何时使用不声明类但具有函数定义的头文件
【发布时间】:2010-10-28 11:53:31
【问题描述】:

我对 C++ 还很陌生,我见过一堆在头文件中有方法定义的代码,它们没有将头文件声明为一个类。有人可以向我解释为什么以及何时会做这样的事情。这是一种不好的做法吗?

提前致谢!

【问题讨论】:

  • 你的意思是无类标题吗?由于 SO 社区中“声明一个类”的不同用法,不确定您所说的“不声明一个类”是什么意思。
  • 是的,我的意思是一个无类标题,我不知道如何解释它。基本上是一个只有一堆函数定义的头文件。

标签: c++ file header


【解决方案1】:

在 C++ 中,函数不必是类的成员。

【讨论】:

  • 不是我自己的答案很好,但我不明白这是如何回答“有人可以向我解释为什么以及何时会做这样的事情。这是一种不好的做法吗?”。显然这是合法的,因为他在工作代码中看到了它。
【解决方案2】:

H 文件只是包含一堆声明的一种方式。 C++ 中的很多东西都是有用的声明,包括类、类型、常量、全局函数等。

C++ 具有强大的面向对象方面。大多数 OO 语言解决了在哪里处理不依赖对象状态且实际上不需要对象的操作的问题。

在某些语言中,例如 Java,语言限制强制所有内容都在一个类中,因此所有内容都成为静态成员函数(例如,具有数学实用程序或算法的类)。

在 C++ 中,为了保持与 C 的兼容性,您可以声明独立的 C 风格函数或使用 Java 风格的静态成员。我个人的观点是,如果可能,最好使用 OO 风格并围绕一个中心概念组织操作。

但是,C++ 确实提供了命名空间设施,并且它的使用方式通常与在这些情况下使用类的方式相同 - 将一组独立项目分组,其中每个项目都以“命名空间”名称为前缀。正如其他人指出的那样,许多 C++ 标准库函数都是这样定位的。我的观点是,这很像在 Java 中使用类。但是,其他人会争辩说 Java 使用类是因为它没有名称空间。 只要您使用其中一个(而不是浮动的独立非命名空间函数),通常就可以了。

【讨论】:

  • 像往常一样,您对 C++ 实践的观察是错误的。 C++ 不“偏爱”类。
  • @Neil:C++ 通常被教授用于面向对象编程,尤其是现在 C 本身已经升级了很多东西以使其更可用。我仍然认为 OOP 更可取。但你真的不必对它这么挑剔。
  • Neil,我希望 Uri 的意思是 C++ 程序员 更喜欢类,这在我的经验中是正确的(尽管是主观的)。
  • C++ 标准库往往会与你们两个相矛盾 - 所有算法都是非成员函数。
  • @Uri 我无法告诉猴子如何教授 C++ - 我对如何使用它很感兴趣。
【解决方案3】:

这是一种不好的做法吗?

一般不会。有很多库是header only,这意味着它们只提供头文件。这个可以被看作是编译库的轻量级替代品。

不过,更重要的是,在某些情况下,您不能使用单独的预编译编译单元:模板必须专门用于声明它们的同一编译单元。这可能听起来很神秘,但它有一个简单的结果:

函数(和类)模板不能在 cpp 文件中定义并在其他地方使用;相反,它们必须直接在头文件中定义(有一些值得注意的例外)。

此外,C++ 中的类完全是可选的——虽然您可以在 C++ 中编写面向对象的程序,但很多好的代码却不能。类是 C++ 中算法的补充,而不是相反。

【讨论】:

    【解决方案4】:

    这不是坏习惯。 C++ 的伟大之处在于它允许您以多种风格进行编程。这为该语言提供了极大的灵活性和实用性,但可能比其他迫使您以特定风格编写代码的语言更难学习。

    如果你有一个小程序,你可以把它写在一个函数中——可能使用几个 goto 来进行代码流。

    当你变得更大时,将代码拆分为函数有助于组织事情。

    更大,类通常是对处理特定数据集的相关函数进行分组的好方法。

    更重要的是,命名空间会有所帮助。

    但有时,编写一个函数来做某事是最简单的。这通常是您编写仅适用于原始类型(如 int)的函数的情况。 int 没有类,所以如果你想写一个 printInt() 函数,你可以让它独立。此外,如果一个函数适用于来自多个类的对象,但实际上并不属于一个类而不属于另一个类,那么作为独立函数可能是有意义的。当您编写诸如define less than之类的运算符以便它可以比较两个不同类的对象时,这种情况经常发生。或者,如果一个函数可以写成类的公共方法,并且不需要直接访问类的数据,那么有些人更喜欢将它写成一个独立的函数。

    但是,真的,选择权在你。解决问题的最简单的方法是最好的。

    您可以从几个函数开始一个程序,然后确定其中一些是相关的并将它们重构为一个类。但是,如果其他独立函数不能自然地融入到一个类中,您不必强行将它们融入到一个类中。

    【讨论】:

      【解决方案5】:

      我对 C++ 还很陌生,我见过一堆在头文件中有方法定义的代码,它们没有将头文件声明为一个类。

      让我们澄清一下。

      头文件中的方法定义

      这意味着这样的事情: 文件“A.h”:

      class A {
      void method(){/*blah blah*/} //definition of a method
      };
      

      这是你的意思吗?

      稍后您会说“声明头文件”。在 C++ 中没有声明文件的机制。通过#include "filename.h" 可以包含一个文件。如果你这样做,头文件的内容将被复制并粘贴到任何你有上述行的地方,然后再编译任何东西。

      所以你的意思是所有的定义都在类定义中(不是在 A.h 文件中的任何地方,而是特别是在类 A 中,受 'class A{' 和 '};' 限制)。 在类定义中包含方法定义的含义是该方法将是“内联”(这是 C++ 关键字),这意味着只要调用它,就会粘贴方法体。这是:

      • 很好,因为函数调用机制不再减慢执行速度
      • 如果函数比短语句长则不好,因为可执行代码的大小增长得非常糟糕

      正如上面所说的那样,模板的情况有所不同,但是对于他们来说,有一种方法可以定义方法,使它们不是内联的,但仍然在头文件中(它们必须在头文件中)。无论如何,这个定义必须在类定义之外。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-21
        • 1970-01-01
        • 2011-08-05
        • 2021-06-16
        • 2018-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多