有没有一种好方法可以避免在C++中出现方法原型的重复?

3
我读过的代码中,大多数C++类方法的签名在声明中通常位于头文件中,在源文件中进行定义。我发现这种重复是不可取的,编写此类代码会导致引用局部性较差。例如,源文件中的方法经常引用在头文件中声明的实例变量;因此,在阅读代码时必须不断在头文件和源文件之间切换。
有人能推荐一种避免这样做的方法吗?或者,如果不按照惯常方式操作,我是否会使有经验的C++程序员感到困惑?
另请参见问题538255 C++代码放在头文件中,其中有人被告知所有内容都应放在头文件中。
5个回答

9
有一种替代方案,但是这种治疗方法比疾病更糟 —— 在头文件中定义所有函数体,甚至在类中内联,就像C#一样。缺点是这会显著增加编译时间,并且会惹恼有经验的C++程序员。它还可能让你陷入一些烦人的循环依赖情况,虽然可以解决,但处理起来很麻烦。
个人而言,我只需将我的IDE设置为垂直分割,将头文件放在右侧,源文件放在左侧即可。

有趣的是,这个答案已经被投票赞同了好几次,而cdiggins的类似答案却被投票踩了。 - Kristopher Johnson
7
可能是因为他认为这是个好主意,而我认为这是个坏主意。 - Crashworks

6
我假设你谈论的是成员函数在头文件中的声明和在源文件中的定义
如果你习惯于Java/Python等语言的模式,这似乎很冗余。 实际上,如果你愿意,你可以在类定义(在头文件中)中内联定义所有函数。 但是,你肯定会违反惯例,并且每次在实现中更改任何细节时都会付出额外的耦合和编译时间的代价。
C++,Ada和其他最初设计用于大型系统的语言保持了定义的隐藏,原因是类的用户无需关心其实现,也没有任何理由他们必须重复支付来编译它。 尽管在现今更快的系统中这不是大问题,但对于真正的大型系统仍然很重要。 此外,隔离和更快的编译使TDD,存根和其他测试策略变得更容易实现。

是的,我已经编辑了问题文本以澄清我所说的是方法声明和定义之间的重复。 - Dickon Reed

4

不要违背惯例。最终,你会产生一个不能很好运行的混乱代码。而且,编译器也会讨厌你。C/C++之所以设置成这样是有原因的。


是的,这也是我的直觉。我很好奇是否还有人愿意提出另一种观点。 - Dickon Reed
3
C++中头文件和实现文件的分离是一种古老的遗物,源于编译相对简单程序可能需要很长时间的时代(我曾在一个系统上工作过,从头开始构建需要超过12个小时)。但这就是它的实现方式,通常应该按照设计来使用工具。 - Kristopher Johnson

3

C++语言支持函数重载,这意味着整个函数签名基本上是识别特定函数的一种方式。因此只要你单独声明定义函数,就不需要再次列出参数,更确切地说,需要列出参数类型并非多余。另一方面,参数名称在此过程中没有作用,你可以在声明(即头文件)中省略它们,尽管我认为这会降低可读性。


0
你“可以”解决这个问题。你需要定义一个抽象接口类,只包含外部应用程序将调用的纯虚函数。然后,在 CPP 文件中,你会提供从接口派生并包含所有类变量的实际类。现在正常实施即可。唯一需要的是一种通过接口类来实例化派生实现类的方法。你可以通过提供一个静态的 “Create” 函数来实现它,该函数在 CPP 文件中实现。
例如:
InterfaceClass* InterfaceClass::Create()
{
     return new ImplementationClass;
}

这样你可以有效地隐藏实现细节,防止外部用户访问。但是,你不能在栈上创建类,只能在堆上创建...但它确实解决了你的问题,并提供了更好的抽象层。不过,如果你没有准备好这样做,那么你需要坚持你正在做的事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接