C++应该消除头文件吗?

70 c++ header-files

许多语言(如Java,C#)不会将声明与实现分开.C#有一个部分类的概念,但实现和声明仍然保留在同一个文件中.

为什么C++没有相同的型号?拥有头文件更实用吗?

我指的是当前和即将推出的C++标准版本.

Gav*_*ler 77

向后兼容性 - 不会消除头文件,因为它会破坏向后兼容性.

  • 如何与向后兼容性并行添加无标题功能.非常像你在与旧c ++并行的编译器中拥有c ++ 11/14支持.然后所有的软件都会很好地发展或优雅地消失. (11认同)
  • +1 - 唯一足以继续使用头文件的原因:/ (9认同)
  • 现代编译器不应该足够聪明,可以根据类实现创建头文件,所以我们不必担心它吗? (2认同)

Ste*_*owe 34

头文件允许独立编译.您无需访问甚至使用实现文件来编译文件.这可以使分布式构建更容易.

这也使得SDK更容易完成.您可以只提供标题和一些库.当然,还有其他语言使用的方法.

  • 显然,轻松不是标题的原因,因为:(1)它们难以维护,它们是重复的代码,(2)对于SDK,它们可以自动提取.我认为分布式构建是正确的. (13认同)
  • 我认为C++标题不会将实现与接口分开.为了获得真正的分离,你必须使用PIMPL或某些抽象. (11认同)
  • Headers以相当原始的方式启用单独的编译和SDK,但它们不需要支持这些东西 - .NET和Java支持两者而不使用头文件. (3认同)
  • 您可以轻松地进行独立编译而无需头文件. (2认同)

Max*_*ert 32

即使是Bjarne Stroustrup也称头文件为kludge.

但是如果没有包含必要元数据的标准二进制格式(如Java类文件或.Net PE文件),我看不到任何实现该功能的方法.剥离的ELF或a.out二进制文件没有您需要提取的大量信息.我认为这些信息并不存储在Windows XCOFF文件中.

  • @Chris Lutz,Kmarsh,夸克.关于一个在大多数人出生之前开发C++的人,你正在谈论(非常无知). (25认同)
  • 如果他发明了头文件,我会更认真地对待Stroustrup先生.然后他会承认自己的错误,而不是诋毁语言,他明确指出这一目标是保持向后兼容的目标.这就像决定制作一个章鱼,然后抱怨你必须戴上多少触手. (5认同)
  • 如果他已经删除了头文件,我会更加认真地对待Stroustrup先生. (3认同)
  • C++标题很难看.在编写良好的C代码中,标题很棒 - 源文件中的私有实现细节是*真正的*私有,并且根本不会暴露给任何人. (2认同)

Mar*_*ier 23

我经常在C#和C++之间翻转,而C#中缺少头文件是我最大的烦恼之一.我可以查看一个头文件,并学习我需要了解的关于一个类的所有内容 - 调用它的成员函数,它们的调用语法等 - 而不必涉及实现该类的代码页面.

是的,我知道部分类和#regions,但它不一样.部分类实际上会使问题变得更糟,因为类定义分布在多个文件中.就#regions而言,它们似乎永远不会像我现在所做的那样以我想要的方式进行扩展,因此我必须花时间扩展这些小的加号直到我得到正确的观点.

也许如果Visual Studio的intellisense更适合C++,我就不会有令人信服的理由不得不经常引用.h文件,但即使在VS2008中,C++的intellisense也无法触及C#

  • 你正在做机器提取文档的工作,并_liking_它.哇... (139认同)
  • 在Java/C#中,您使用Interfaces来显示api.这是显示API而不是头文件的更好方法.单独的类文件用作实现. (25认同)
  • 让我们看看你使用标题来检查std :: vector ...或任何其他std集合类的接口......或者在boost中完全没有任何东西......所有这些对于这个目的来说都是完全没用的. (20认同)
  • 任何适当的IDE都将为您提供有关类和方法的所有信息.由于您提到的是VS2008,因此使用对象浏览器可提供完整的文档并轻松搜索和浏览.你还需要什么?您是否认为浏览头文件页面更容易? (18认同)
  • 是但是......没有走得更远,C++头文件混合了实现细节和公共合同. (11认同)
  • kts,你通常没有任何接口.很多API都在具体的类中.您通常使用专用的文档提取工具来显示API,一个生成HTML或一个嵌入IDE(VS中的对象资源管理器) (3认同)
  • 我同意马克.头文件是存储基本文档的好地方; 下一级详细信息是手册页/ MSDN.通过涉及代码,我并没有特别提高我的工作效率. (3认同)
  • 如果您使用头文件查看类的成员,那么您还没有学会正确使用Visual Studio.尝试查看导航栏,类视图或对象资源管理器.如果这还不够,您可以随时编写自己的工具来处理编译器生成的XML文档文件.C#用于浏览类的工具远远超过C++,我甚至无法开始为它找到单词. (3认同)
  • VS'intellisense的限制是由于它来自他们的命令行C++编译器通过ifdefs.这是正在纠正的,并且c ++的intellisense应该在VS10中大大改进:http://blogs.msdn.com/vcblog/archive/2009/01/27/dev10-is-just-the-beginning.asp (2认同)

Abh*_*hay 18

C++的设计和演变中,Stroustrup提出了另一个原因......

相同的头文件可以具有两个或更多个实现文件,这些文件可以由多个程序员同时处理,而不需要源控制系统.

这些可能看起来很奇怪,但我想这是C++发明时的一个重要问题.

  • +1 for*相同的头文件可以有两个或更多的实现文件*.对于在不滥用`#ifdef`-fu的情况下进行便携式应用程序而言,这是天赐之物.(只需使用一个生成文件,从平台依赖的`myclass-win.cpp` /`myclass-linux.cpp`生成正确的`myclass.o`,外面只关心`myclass.h`) (9认同)

Bil*_*l K 15

C是为了轻松编写编译器.它基于这一原则做了很多事情.仅存在指针使编写编译器更容易,头文件也是如此.转移到C++的许多东西都是基于与实现的这些功能的兼容性,以使编译器编写更容易.

实际上这是一个好主意.当C被创建时,C和Unix就是一对.C移植Unix,Unix运行C.这样,C和Unix可以迅速从平台传播到平台,而基于程序集的操作系统必须完全重写才能移植.

在一个文件中指定接口和在另一个文件中指定实现的概念根本不是一个坏主意,但这不是C头文件.它们只是一种限制编译器必须通过源代码传递的数量的方法,并允许对文件之间的契约进行一些有限的抽象,以便它们可以进行通信.

这些项目,指针,头文件等......并没有真正提供优于其他系统的任何优势.通过在编译器中投入更多精力,您可以像指向完全相同的目标代码的指针一样轻松地编译引用对象.这就是C++现在所做的.

C是一种很棒的简单语言.它的功能集非常有限,您可以毫不费力地编写编译器.移植它通常是微不足道的!我不是说它是一种糟糕的语言或任何东西,只是C的创建时的主要目标可能会留下现在或多或少不必要的语言中的残余,但是为了兼容性将保留它们.


似乎有些人并不真的相信C是写入端口Unix的,所以这里:( 来自)

UNIX的第一个版本是用汇编语言编写的,但Thompson的意图是它将用高级语言编写.

汤普森于1971年首次尝试在PDP-7上使用Fortran,但在第一天之后放弃了.然后他写了一个非常简单的语言,他称之为B,他开始使用PDP-7.它有效,但有问题.首先,因为解释了实现,所以它总是很慢.其次,基于面向字的BCPL的B的基本概念对于像新PDP-11这样的面向字节的机器来说是不对的.

Ritchie使用PDP-11向B添加类型,有一段时间被称为NB为"New B",然后他开始为它编写编译器."所以C的第一阶段确实是这两个阶段的短暂连续,首先,一些语言从B改变,实际上,在语法中没有太多变化的情况下添加了类型结构;并且做了编译器,"Ritchie说.

"第二阶段的速度较慢,"他谈到重写UNIX中的UNIX.汤普森在1972年夏天开始但有两个问题:弄清楚如何运行基本的协同程序,即如何将控制从一个过程切换到另一个; 并且难以获得正确的数据结构,因为C的原始版本没有结构.

"这些事情的结合导致肯在夏天放弃,"里奇说."在过去的一年里,我添加了结构,可能使编译器代码更好 - 更好的代码 - 所以在接下来的夏天,那是我们齐心协力,实际上用C重做了整个操作系统."


这是我的意思的完美例子.来自评论:

仅存在指针使编写编译器更容易?没有.指针存在是因为它们是对间接思想最简单的抽象. - Adam Rosenfield(一小时前)

你是对的.为了实现间接,指针是最简单的实现抽象.它们绝不是最容易理解或使用的.数组更容易.

问题?要像指针一样有效地实现数组,您必须在编译器中添加大量代码.

他们没有理由没有指针设计C,但代码如下:

int i=0;
while(src[++i])
    dest[i]=src[i];
Run Code Online (Sandbox Code Playgroud)

将需要花费大量精力(在编译器部分)来分解显式的i + src和i + dest添加,并使其创建相同的代码:

while(*(dest++) = *(src++))
    ;
Run Code Online (Sandbox Code Playgroud)

在事实之后考虑变量"i"是很难的.新的编译器可以做到这一点,但当时它是不可能的,并且在那些糟糕的硬件上运行的操作系统需要很少的优化.

现在很少有系统需要这种优化(我在一个最慢的平台上工作 - 有线机顶盒,我们的大多数东西都是Java),在极少数情况下你可能需要它,新的C编译器应该足够聪明,能够自己进行这种转换.

  • 任何说编写C编译器很简单的人都从未编写过C编译器. (7认同)
  • 仅存在指针使编写编译器更容易?没有.指针存在是因为它们是对间接思想最简单的抽象. (5认同)
  • Pascal的目的是简化编写编译器.您可以使用简单的手动编码递归下降解析器.C更复杂. (2认同)
  • C是在操作系统中取代汇编语言的早期尝试.D&R正准备在硅片上实际编程.这就是指针的原因,而不是另一种抽象.他们想要一个明确的方法来完成他们在汇编程序中所做的事情. (2认同)
  • 我对Pascal的观点是,如果主要的C设计目标很容易实现,K&R可以并且本来可以做得更好.这并不困难. (2认同)

Jer*_*rks 14

如果你想要没有头文件的C++,那么我对你有好消息.

它已经存在并被称为D(http://www.digitalmars.com/d/index.html)

从技术上讲,D似乎比C++好很多,但它目前还不够主流,无法用于许多应用程序.

  • D*是*系统编程语言.用D编写的操作系统内核:http://xomb.org/ (3认同)
  • 无论你是否使用它,D的关键点在于它具有C++的大部分功能集.您可能认为C++需要头文件,因为模板需要它们,或者因为您需要有效代码而需要它们.D的存在表明这两者都是假的. (2认同)

小智 8

C++的目标之一是成为C的超集,如果它不能支持头文件,它很难这样做.并且,通过扩展,如果您希望切除头文件,您可以考虑完全切除CPP(预处理器,而不是加号); C#和Java都没有指定带有标准的宏预处理器(但在某些情况下应该注意它们甚至可以用于这些语言).

由于C++目前正在设计,您需要原型 - 就像在C中一样 - 来静态检查引用外部函数和类的任何编译代码.如果没有头文件,则必须在使用它们之前键入这些类定义和函数声明.对于C++不使用头文件,您必须使用支持Java import关键字之类的语言添加一个功能.那将是一个重大的补充和改变; 回答你是否实际的问题:我不这么认为 - 根本不是.


Pio*_*ost 8

许多人都意识到头文件的缺点,并且有想法将更强大的模块系统引入C++.您可能想看看Daveed Vandevoorde的C++模块(修订版5).