gpt4 book ai didi

c++ - 有人熟悉 “implementation/internal header”(* .ih)吗?

转载 作者:太空狗 更新时间:2023-10-29 23:53:24 26 4
gpt4 key购买 nike

在F.B.开设的C++半年类(class)中Brokken(The C++ Annotations的作者),我们被教导使用所谓的实现 header 。我知道这是弗兰克的惯例,但我从没看过其他地方。因此,我将解释这个概念,并且我很好奇其他人对此的看法。

这个想法是,您只需将类成员的实现的实现所需的所有#include指令(假设您未编写类中的定义)放入一个文件,.ih实现 header ,并将此文件#include放入而是每个源文件。替代品是
1)#include类标题中的所有内容或
2)在每个源文件中分别对所有 header #include编码。

两种选择的缺点都很明显:
1a)您必须在添加任何需要一些其他#include的内容之后,重新编译所有源#include到此 header 。
1b)您的头文件(应该是类的清晰接口(interface))被一大堆#include指令污染了,用户不知道该指令的用途,他也不在乎。
2a)您必须在每个源文件中一次又一次地对相同的 header #include
2b)您的实现受到所有这些#include的污染,使其看起来有些困惑。

只是要清楚:

/* someclass.h(pp) */

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

class SomeClass
{
//some private data members
public:
SomeClass();
void sayHi() const;
// some more member functions
private:
// some private member functions
};

#endif

/* someclass.ih */

#include "someclass.h"
#include <iostream>
#include <vector>
using namespace std;

// namespace is now only used in my implementations, other people
// including my headers won't accidentally import the entire std namespace.

/* sayhi.cc */

#include "someclass.ih"

void SomeClass::sayHi() const
{
cout << "sayHi() says hi!\n";
}

现在,问题又来了:有人听说过这样的约定吗?我是否说服任何人开始使用它?我个人认为它是一个非常有用(甚至很明显)的约定,但是我在其他地方都没有看到它,对此我感到有些惊讶。

最佳答案

有趣的帖子。让我首先评论关于.ih header 的user1428839的声明(以下称为发帖人):

首先,海报写道:

...The idea is that you just put all #include directives that are needed by the implementations of your class-members' implementations ... in one file, the .ih implementation header, and #include this file in every source file instead.



按照规定,这是不正确的。为避免混淆,句子的最后一部分应为:.ih文件所属的类的每个源文件中的...。在.ih方法下,类头文件(例如 someclass.h)仅提供接口(interface),并且仅应声明可以声明的内容。因此,如果 SomeClass具有类数据成员 std::ofstream *d_out,则无需 #include <fstream>。相反,它足以满足 #include <iosfwd>的要求。这将产生一个干净的类接口(interface),当不属于但仅使用 SomeClass的源包含它时,可将其编译时间降至最低。

接下来,海报指出:

1a) You have to recompile all sources #include'ing this header after adding anything that requires some additional #include's.



那不是真的。仅在接口(interface)中实际使用附加 header 声明的功能时才需要这样做。如果不是这样,则不需要完全重新编译。如果添加了新的数据成员,或者在类接口(interface)中使用了附加 header 的元素(例如,这是不好的样式,例如,您使用内联成员),则需要完全重新编译。

海报提出的下一点:

1b) Your header file, that is supposed to be a clear interface of your class, gets polluted with a great bunch of #include directives of which the user has no idea what they are used for, nor does he care.



正确,但是这里的重点是类头变得太胖了。每当外部源需要包括 someclass.h时,编译器还必须读取所有这些附加头,以及那些头所包含的头等,而编译器仅需要知道 SomeClass的本质。谚语是用户不必为自己不需要的东西付费,在这种情况下,由于编译器不得不读取(通常是很多)无用的(在 SomeClass的情况下)头文件而导致的额外编译时间。

张贴者建议使用.ih约定的替代方法之一是在需要的地方包含所需的内容。实际上,我认为这是一个很好的选择,但它也需要大量记账和工作。通常,类成员实现需要相同的头文件,并将它们放在一个文件中,实现头具有定义一个维护点的额外好处。是的,当编译器偶尔需要读取特定源不需要的 header 时,会产生很小的开销,但这仅发生一次:在类编译时(希望(大概)仅偶尔发生)。

恐怕对海报发布者的某些反应是对.ih方法的核心点稍有误解的结果:
  • 类头本身保持尽可能小的
  • 使用该类的源的编译时间不会比严格要求的
  • 更长。
  • 类开发人员不必一次又一次地包含编译类成员所需的一堆头文件。取而代之的是,仅需要包含一个适合该类要求的标题。

  • DeadMG的另一个答复集中在将所有源放入一个源文件中。在某种程度上,这只是风格问题。如果您为一个特定的程序开发软件,那么也可以将所有源文件放在一个文件中,如果这适合您的个人喜好。我个人觉得这很烦人,而且很难使用这些文件,因为我经常喜欢同时查看或使用许多功能的源代码,但最后当然要随心所欲。

    但是,如果您开发软件的目的是以后在其他程序中重用它,例如,您开发了一个考虑将其添加到库中的类,那么您绝对应该使用“一功能一文件”方案。考虑一下构造函数:类通常提供一系列构造函数,然后选择适合您上下文的构造函数。如果将类的实现放到一个源文件中,那么您的最终程序将变得多余,因为链接器必须将实现构造函数的目标文件以及该程序所需的目标文件添加到程序中,等,等等。因此,您最终获得了一个毫无意义的,链接到许多其他目标文件的程序。一功能一文件原则可防止这种情况的发生。

    关于c++ - 有人熟悉 “implementation/internal header”(* .ih)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11063355/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com