如果我讨厌C ++头文件怎么办?


25

我总是对头文件感到困惑。它们是如此奇怪:您包含的.h文件不包含.cpp,但.cpp也已通过某种方式进行编译。

最近,我加入了一个团队项目,并且当然使用.h和.cpp。
我知道这非常重要,但是我不能忍受复制粘贴我们拥有的多个类中的每个类中的每个函数声明。

如何有效处理2个文件的约定?
是否有任何工具可以帮助您解决此问题,或自动将以下示例中的一个文件更改为.h和.cpp?(特定于MS VC ++ 2010)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...

8
这个问题可能有两种方式:“为什么使用c ++时我们需要标头”或“您认为应该编译的现代语言应该使用标头?” 正因为如此,它有“我该怎么办”和‘为题恨’,这衬托标志的太多了。
蒂姆后

4
您的问题使您似乎不了解C ++,或者您使用的任何系统如何编译C ++。学习正确使用它,然后提出更多主观问题。
David Thornley

31
您的第一句话表示您不“了解标题的所有内容”。包含.h文件不会导致相应的.cpp文件也被“某种程度地编译”。您可以自行编译.cpp文件。如果尚未编译相应的.cpp,则包含没有相应目标文件的标头将导致链接器失败。
Paul Butcher

5
该怎么办?如果对您造成很大的困扰,请寻找另一种语言。
保罗·内森

5
关于“不能复制粘贴”:每当更新一个函数时,无论如何都必须更新所有被调用的地方。由于调用者比头文件中的声明难于查找,因此更新头只是次要的细节。
Sjoerd

Answers:


15

编写更多重构友好的C ++

在C ++中,你不具备在所有使用页眉。您可以像使用C#或Java一样在一个文件中定义整个对象。C开发人员通常只会将外部调用保留在头文件中。所有内部调用都将在.c文件中定义。同样,您可以为类/接口(纯虚拟抽象类)/ etc保留C ++ .h文件。旨在在DLL之外共享的文件。对于内部类/结构/接口等,您只需包含所需的.cpp文件:

#include<myclass.cpp>

这似乎不是最受欢迎的方法,但它是合法的C ++。您的所有内部代码绝对有可能。这允许内部代码和类集进行更大的改变,同时为库/可执行文件之外的代码提供更稳定的接口。

将整个班级放在一个文件中将使您更轻松地完成自己想要的事情。它不会解决重命名方法以及必须搜索该方法被调用的每个位置的问题,但是它将确保您拥有更多可理解的错误消息。没有什么比让标头以一种方式声明方法更糟糕了,但是您以不同的方式实现它。其他调用头文件的代码将正确编译,并且您将获得链接异常,而实现文件将是抱怨该方法未定义的文件。当您在实际的类声明中定义每个方法时,无论包含哪个文件,都将得到相同的错误消息。

您可能还想看一下这个问题:C ++的良好重构工具

C / C ++如何解析头文件/实现文件

在基础C级别上(并且C ++是在此基础上构建的),头文件声明了函数/结构/变量的承诺,该承诺足以允许编译器创建目标文件。类似地,C ++头文件声明了函数,结构,类等的承诺。编译器使用此定义在堆栈中保留空间等。

.c或.cpp文件具有实现。当编译器将每个实现文件转换为目标文件时,存在未实现概念(在标头中声明的内容)的钩子。链接器将挂钩与其他目标文件中的实现联系起来,并创建一个包含所有代码(共享库或可执行文件)的较大二进制文件。

VS特定

至于使用Visual Studio中的工具,有一些向导可以使事情变得简单一些。新的类向导将创建匹配的头文件和实现文件对。甚至有一个类浏览器功能,将允许您声明新方法。它将在.cpp文件的标头和实现存根中注入定义。Visual Studio拥有这些功能已有十多年了(只要我使用过它们)。


问题是,我一直在大量修改类,而不仅仅是添加新功能,等等
Oleh Prypin 2011年

5
@BlaXpirit:那么,为什么要一直在大量修改类?OO设计的想法之一是拥有许多相当稳定的构建基块。如果我要大量修改类,那么我想使用一种更动态的语言,例如Common Lisp或Python。
David Thornley

2
那就是我在做的 我正在改进/修改“构件”并添加新的
构件

C ++从来没有重构过友好的。直到有一些工具使重构在Java IDE中变得非常容易时,重构的概念才发展起来。注意:这些功能适用于Smalltalk开发人员和其他语言,但是直到很多人都可以使用它时,它才成为主流。到目前为止,我还没有看到有人为C ++聪明地实现它。也许是JetBrains的Resharper?我知道它可以执行C#和VB代码,但是我不确定它是否可以为您提供C ++重构。
Berin Loritsch 2011年

@Berin:一两年前我去寻找C ++重构工具,发现了两件事。当时它们的价格相当昂贵,而且我没有看到试用版,所以我不知道它们的功能。而且,只有一个人使用emacs,这将限制其在Visual Studio商店中的有效性。
David Thornley

13

成为Java开发人员。

如果确实必须使用C ++进行开发,则可以尝试使用IDE。通常,它们提供了某种机制,您可以通过该机制将方法添加到类中,并且自动将声明放置在.h文件中,并将定义放置在.cpp文件中。


2
kthx,我有点了解Java,但是您不能使用它制作低级Win32 DLL,可以吗?
Oleh Prypin 2011年

41
我不知道为什么,但是“成为Java开发人员”听起来有点像侮辱:D。
奥利弗·韦勒

2
如果您想做低级课程,请不要忘记有关“简单语言”的所有内容。低水平消耗汗水和眼泪。
Batibix 2011年

5
这不是一个特别有用的答案。
ChrisF

1
@OliverWeiler我不认为“成为Java开发人员”是一种侮辱。我同时使用C ++和Java进行编程,但到目前为止,我更偏爱Java,因为坐下来并敲打可以工作的代码非常容易(并且更具可移植性)。如果出于某种原因而讨厌头文件的存在,则尝试Java是正确的选择(尽管很奇怪,您会讨厌头文件;我会考虑在IDE中进行更改)。
Trixie Wolf


4

当您编写新类的第一行时,通常是因为您仅在那时才需要它。以后可能会在更多地方使用它,但最初通常不使用它。

我的许多课程都从当前.cpp文件的顶部开始。当它稳定到足以在多个地方使用时,我将其剪切粘贴到标题中。尽管课程经常以消失的速度消失。


-1

作为帮助处理C ++头文件的建议,通常在不使用文件扩展名或文件后缀的情况下使用它们,例如“ GCC”库。

如果是这种情况,建议您使用“ .hpp”(或最少的“ .hxx”)文件扩展名或文件后缀。

您可能必须配置编译器,开发人员环境或内置程序。


3
您是在谈论如何添加类似文件#include <iostream>吗?这些不仅仅用于GCC库。实际上,它是在1997 C ++标准第17.3.1.2节中定义的。我会避免这样命名文件。您可以,但是C ++标准库这样做的原因可能是避免命名冲突。当编译器在添加标头时自动添加“ .h”时,我发现它确实很奇怪,这对我来说似乎很不规范。而且,除了c ++标准库外,我从未见过任何没有后缀的名称标头。
vedosity 2011年

1
另外,我应该注意,我使用的所有编译器(除了borland(我非常讨厌))在尝试时都不会自动添加“ .h”或“ .hpp”或“ .hxx”包括没有后缀的文件。不要期望在所有编译器上都#include <someclass>读成#include <someclass.hpp>。您的代码将中断。
vedosity 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.