3

大多数 C++ 类方法签名通常在头文件中的声明和我已阅读的代码中的源文件中的定义之间重复。我发现这种重复是不可取的,并且以这种方式编写的代码存在引用局部性差的问题。例如,源文件中的方法经常引用头文件中声明的实例变量;你最终不得不在阅读代码时不断地在头文件和源文件之间切换。

有人会推荐一种避免这样做的方法吗?或者,我主要是因为不以通常的方式做事而使有经验的 C++ 程序员感到困惑吗?

另请参阅问题 538255 C++ 代码在头文件中,有人被告知所有内容都应该放在头文件中。

4

5 回答 5

9

有一个替代方案,但治标不治本——在头文件中定义所有函数体,甚至在类中内联,如 C#。缺点是这会显着增加编译时间,并且会惹恼资深的 C++ 程序员。它还可能使您陷入一些令人讨厌的循环依赖情况,虽然可以解决,但处理起来却很麻烦。

就个人而言,我只是将我的IDE设置为垂直拆分,并将头文件放在右侧,将源文件放在左侧。

于 2009-10-30T11:26:43.067 回答
6

我假设您正在谈论头文件中的成员函数声明和源文件中的定义?

如果你习惯了 Java/Python/etc. 模型,它可能看起来是多余的。事实上,如果您愿意,您可以在类定义中(在头文件中)内联定义所有函数。但是,每次更改实现中的任何细微之处时,您肯定会打破惯例并付出额外的耦合和编译时间的代价。

最初为大型系统设计的 C++、Ada 和其他语言将定义隐藏是有原因的——一个类的用户没有理由必须关心它的实现,也没有任何理由他们应该重复付费编译它。如今,对于更快的系统来说,问题不大,但仍然与真正的大型系统相关。此外,隔离和更快的编译有助于 TDD、存根和其他测试策略。

于 2009-10-30T11:29:34.950 回答
4

不要打破常规。最后,你会做出一个不太好用的蠕虫球。另外,编译器会讨厌你。C/C++ 以这种方式设置是有原因的。

于 2009-10-30T11:18:29.493 回答
3

C++ 语言支持函数重载,这意味着整个函数签名基本上是一种识别特定函数的方式。出于这个原因,只要你分别声明定义函数,不必再次列出参数真的没有冗余。更准确地说,必须列出参数类型并不是多余的。另一方面,参数名称在此过程中不起作用,您可以在声明中(即在头文件中)随意省略它们,尽管我相信这会限制可读性。

于 2009-10-30T14:10:22.217 回答
0

你“可以”解决这个问题。您定义一个抽象接口类,它只包含外部应用程序将调用的纯虚函数。然后在 CPP 文件中提供从接口派生并包含所有类变量的实际类。您现在正常实施。唯一需要的是一种从接口类实例化派生实现类的方法。您可以通过提供在 CPP 文件中实现的静态“创建”函数来做到这一点。

IE

InterfaceClass* InterfaceClass::Create()
{
     return new ImplementationClass;
}

通过这种方式,您可以有效地向任何外部用户隐藏实现。但是,您不能仅在堆上在堆栈上创建类......但它确实解决了您的问题并提供了更好的抽象层。最后,如果你不准备这样做,你需要坚持你正在做的事情。

于 2009-10-30T11:33:27.887 回答