类成员函数声明疑惑

3
我正在阅读一份C++教程,遇到了这句话:
“在类内完全定义一个成员函数或仅包含原型并稍后定义它的唯一区别是,在第一种情况下,编译器将自动将该函数视为内联成员函数,而在第二种情况下,它将是一个普通(非内联)类成员函数,实际上在行为上没有任何区别。”
我知道什么是内联函数,但我不确定应该选择哪种方式。我应该在其类内部定义每个函数还是在外部定义?也许将最简单的函数放在类内部,其他函数放在外面?
我担心在类内部定义每个函数(即具有复杂的内联函数)可能会弄乱生成的代码,并在执行期间引入调试问题或奇怪的行为。最后,还有“编码风格”问题。
那么,哪种方法更好呢?
谢谢 :)

“Better” 从哪个角度来看?我倾向于将代码的阅读者/维护者作为首要关注点。性能只有在分析器指出需要优化时才是次要关注点。 - David Hammen
@David Hammen:这是“编码风格”的问题。但现在我只是一个业余程序员,这个问题几年内不会成为问题 ;) - BlackBear
1
也许六个月后你无法解读自己半年前写的代码,这可能会成为你的问题。也许你自己是代码中最重要的读者。 - David Hammen
5个回答

1

我的风格:有时我会将极短的函数(一两行)放在类本身中。任何更长的我仍然想作为内联函数的东西都会作为类定义后的inline限定实现,而且通常在一个单独的文件中,该文件在类定义的末尾进行#include

将内联函数放在类外部的原因是,某些函数的实现通常会妨碍人类读者对类的整体理解。一个二十行的函数通常可以用一行注释来概括--当你阅读类定义时,这个注释就足够了。如果你需要更多,请查看函数定义,或者更好的是,阅读精细文档。(期望别人阅读代码是优秀文档的劣质替代品。)


0

两种方法并没有本质上的优劣之分,这只是个人偏好和风格问题。就我个人而言,我认为在单独的 .inline 文件中明确定义函数是最好的方式。这样你可以非常明确地表达你所做的事情,并保持头文件的清洁。

此外,如果您使用以下定义的宏 INLINE:

#ifdef DEBUG 
    #define INLINE
#else
    #define INLINE inline
#endif

然后您可以在发布版本中从头文件中包含内联文件,在调试版本中从 CPP 中包含。这意味着,即使编译器在调试时内联函数,您在调试时也不会遇到任何困难。不过,必须承认的是,对于现代编译器来说,这并不是一个大问题,因此,除非使用旧编译器,否则您可能想跳过此步骤。


0

回答“哪种方法更好?”的部分 - 来自C++ FAQ -

没有简单的答案:您必须尝试一下才能知道哪个最好。不要满足于像“永远不要使用内联函数”或“总是使用内联函数”或“仅当函数少于N行代码时使用内联函数”这样的简单答案。这些一刀切的规则可能很容易写下,但它们会产生次优结果。


0

一般来说,只有一两个语句的成员函数最好在类声明中编写其主体,特别是如果有很多这样的函数。具有20-50个以上语句的成员函数最好不要在类声明中。对于长度和复杂性之间的情况,它取决于许多因素。

例如,在类模块中拥有函数主体可以帮助防止在类声明不改变时重新编译依赖模块的不必要操作,仅重新编译成员函数主体。这可以极大地提高开发类时的生产力。一旦类稳定下来,这就不那么重要了。


0

最好的解决方案是将接口和实现分开。接口是你的头文件(h-file)。只放原型在那里。实现部分则放到 cpp 文件中。这种方法具有以下优点:

  1. 编译速度更快,因为不需要多次编译函数体。
  2. 头文件依赖性更简单,因为不需要在 h-file 中包含所有头文件。一些头文件仅在 cpp-file 中需要,并且可以在 h-file 中使用前向声明。还可以避免循环依赖。
  3. 最后但并非最不重要的是,更容易让人类理解类的接口。没有代码混乱。

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