首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内联我的C++应用程序的几乎所有方法是一个好主意还是坏主意?

内联我的C++应用程序的几乎所有方法是一个好主意还是坏主意?
EN

Software Engineering用户
提问于 2018-09-05 00:37:16
回答 3查看 3.9K关注 0票数 4

我习惯于D编码和Python,其中类定义也包含每个方法定义。所以这是我最喜欢的编码风格。

我讨厌切换到.cpp文件并使用那个长限定符名。

所以,由于我很少调用一个函数超过2-3次,所以将我的大部分代码内联不是一个好主意吗?我的代码不是库。这是一个供数学家使用的桌面应用程序。

这对我来说很有意义。这样可以吗?谢谢。

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2018-09-05 07:14:41

在编写C++时,不要像编写Python、D或Java那样编写它。那是基本不同的语言和不同的习语

当我们在C++中讨论内联函数时,我们必须区分两个相关但不同的概念:

  • inline在标头中起作用。类声明中的函数定义是隐式inline。模板通常是内联的。inline函数(或变量)实际上禁用了一元定义规则(ODR):如果链接器在不同的编译单元中看到相同函数的多个相互冲突的定义,链接器通常会显示一个错误。但是对于inline函数,您可以保证所有定义都是相同的。此外,内联函数只能从定义它的同一编译单元调用。
  • 内联作为编译器优化。inline函数的语义使内联成为可能,但inline关键字并不意味着函数将内联。例如,内联定义的成员函数不能通过间接调用(例如虚拟调用)进行内联。
    • 您可以通过为非inline函数提供内部联动,或者通过免费函数/变量的static关键字(但不是成员!),使它们的内联成为可能!或者通过使用匿名命名空间。
    • 您可以使用编译器特定的属性。例如,__attribute__ ((always_inline))GCC

不宜在标头中内联定义所有函数。

  • 这会减慢编译时间。通过使用多个编译单元,您可以从增量编译中获益。这使得除了最琐碎的C++项目之外的任何一个项目的工作都更令人愉快。但是,如果您将不必要的代码放入头中,则每次都必须对其进行分析、编译和优化。由于模板通常意味着头中的内联定义,所以这些编译时间是某些项目试图限制模板使用的原因之一。
  • 它导致名称空间污染和缺乏封装。相当多的代码往往需要一些私人助手。在Python中,我会在模块中添加一个下划线-函数,在C++中添加一个静态函数或匿名命名空间中的一些代码,以便它们仅限于当前的编译单元。但是,当所有内容都在标题中时,您只有一个编译单元。所有这些帮助程序在所有代码中都是可见的,并且您实际上没有内部结构。这也可能导致姓名冲突。
  • 此外,请考虑如何包含标头。在通常的头-实现分离中,只能在内部需要的头,而不需要模块的公共接口的头,可以包含在.cpp文件中。这限制了标头的效果,例如,对于任何宏或全局函数。在与C库进行接口时,这一点尤为重要。这还将使您能够在提供冲突名称的库之间架起桥梁。当您的所有代码都在头中时,情况就不是这样了。所有包含的定义也将在包含头的所有编译单元中可见。
  • 内联定义仅在依赖项可以线性化时才能工作,但不适用于循环或递归依赖项(例如表示树节点的类)。即使将代码放入标头中,也可能需要使用前向声明或定义类声明之外的方法。如果该方法不必是inline,那么在标头中定义它将一无所获。

如果您不喜欢经常在头文件和实现文件之间切换,我建议您考虑使用一个IDE,它可以让您更容易地在声明和相应定义之间切换。

是的,C/C++可以是非常烦人的语言,因为它们具有历史意义。是的,Java代码读起来更好。但是,尝试编写C++不会有任何好处,就好像它是Java一样。你就会放弃C++所能提供的好处。类似地,现代C++避免使用new创建对象,因为这实际上放弃了RAII。

票数 17
EN

Software Engineering用户

发布于 2018-09-05 06:56:03

如果内联是指使用inline函数,则不需要:

  • 主流编译器现在执行全局优化,如果它具有真正的性能优势,它将自动为您执行。
  • 该标准的措辞表明,您不会对编译器的操作产生太大影响:在调用点执行这种内联替换不需要实现。
  • 主要区别在于您是否在标头中定义了一个函数。使用inline关键字,编译器将允许头包含在多个地方,可以理解它在任何地方都是相同的函数。如果没有inline,如果同一个标头包含在不同的单元中,则可能会破坏一个定义规则(ODR)。

如果您所说的内联意味着将成员函数定义放在标题中的类定义中,那么这个实践并不是推荐的做法。如果在每个编译单元中对同一个类使用完全相同的令牌序列,则不会破坏ODR规则。但是有几件事情更难做(特别是当两个类之间存在一些相互依赖时)。将类定义与其实现分离,具有鼓励封装的优点。

票数 5
EN

Software Engineering用户

发布于 2018-09-05 09:23:23

我真的很喜欢一个记录良好的头文件,它只告诉我我想知道的东西:类和方法名称,方法的规格是什么。我不想看你的源代码。这只会让我更难读到我想要的东西。

Swift很好地做到了这一点:按照您想要的方式编写代码,如果我想看到它们,IDE会生成头文件,并且它们只包含感兴趣的内容(比如没有私有方法或属性)。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/377949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档