我可以编写没有头文件的 C++ 代码(重复的函数声明)吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1001639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:21:47  来源:igfitidea点击:

Can I write C++ code without headers (repetitive function declarations)?

c++headerheader-files

提问by thewreck

Is there any way to not have to write function declarations twice (headers) and still retain the same scalability in compiling, clarity in debugging, and flexibility in design when programming in C++?

有什么方法可以不必编写两次函数声明(头文件),并且在用 C++ 编程时仍然保持相同的编译可扩展性、调试清晰度和设计灵活性?

回答by Richard Corden

Use Lzz. It takes a single file and automatically creates a .h and .cpp for you with all the declarations/definitions in the right place.

使用Lz。它需要一个文件,并自动为您创建一个 .h 和 .cpp,并在正确的位置包含所有声明/定义。

Lzz is really very powerful, and handles 99% of full C++ syntax, including templates, specializations etc etc etc.

Lzz 真的非常强大,可以处理 99% 的完整 C++ 语法,包括模板、专业化等等。

Update 150120:

更新 150120:

Newer C++ '11/14 syntax can only be used within Lzz function bodies.

较新的 C++ '11/14 语法只能在 Lzz 函数体内使用。

回答by rix0rrr

I felt the same way when I started writing C, so I also looked into this. The answer is that yes, it's possible and no, you don't want to.

当我开始写 C 时,我也有同样的感觉,所以我也研究了这个。答案是,是的,这是可能的,不,你不想。

First with the yes.

首先是肯定的。

In GCC, you can do this:

在 GCC 中,您可以这样做:

// foo.cph

void foo();

#if __INCLUDE_LEVEL__ == 0
void foo() {
   printf("Hello World!\n");
}
#endif

This has the intended effect: you combine both header and source into one file that can both be included and linked.

这具有预期的效果:您将标头和源代码合并到一个既可以包含又可以链接的文件中。

Then with the no:

然后没有:

This only works if the compiler has access to the entire source. You can't use this trick when writing a library that you want to distribute but keep closed-source. Either you distribute the full .cph file, or you have to write a separate .h file to go with your .lib. Although maybe you could auto-generate it with the macro preprocessor. It would get hairy though.

这仅在编译器可以访问整个源代码时才有效。在编写要分发但保持闭源的库时,不能使用此技巧。要么分发完整的 .cph 文件,要么必须编写一个单独的 .h 文件与 .lib 一起使用。虽然也许您可以使用宏预处理器自动生成它。不过会毛茸茸的。

And reason #2 why you don't want this, and that's probably the best one: compilation speed. Normally, C sources files only have to be recompiled when the file itself changes, or any of the files it includes changes.

原因 #2 为什么你不想要这个,这可能是最好的一个:编译速度。通常,C 源文件仅在文件本身发生更改或其中包含的任何文件发生更改时才需要重新编译。

  • The C file can change frequently, but the change only involves recompiling the one file that changed.
  • Header files define interfaces, so they shouldn't change as often. When they do however, they trigger a recompile of every source filethat includes them.
  • C 文件可以频繁更改,但更改仅涉及重新编译更改的一个文件。
  • 头文件定义了接口,因此它们不应该经常更改。但是,当它们这样做时,它们会触发对包含它们的每个源文件的重新编译。

When all your files are combined header and source files, every change will trigger a recompile of all source files. C++ isn't known for its fast compile times even now, imagine what would happen when the entire project had to be recompiled every time. Then extrapolate that to a project of hundreds of source files with complicated dependencies...

当您将所有文件合并为头文件和源文件时,每次更改都会触发所有源文件的重新编译。即使现在 C++ 也不以其快速的编译时间而闻名,想象一下如果每次都必须重新编译整个项目会发生什么。然后将其推断为具有复杂依赖关系的数百个源文件的项目......

回答by ojrac

Sorry, but there's no such thing as a "best practice" for eliminating headers in C++: it's a bad idea, period. If you hate them that much, you have three choices:

抱歉,但在 C++ 中没有消除头文件的“最佳实践”:这是一个坏主意,句号。如果你那么讨厌他们,你有三个选择:

  • Become intimately familiar with C++ internals and any compilers you're using; you're going to run into different problems than the average C++ developer, and you'll probably need to solve them without a lot of help.
  • Pick a language you can use "right" without getting depressed
  • Get a tool to generate them for you; you'll still have headers, but you save some typing effort
  • 熟悉 C++ 内部结构和您正在使用的任何编译器;您将遇到与普通 C++ 开发人员不同的问题,您可能需要在没有很多帮助的情况下解决它们。
  • 选择一种您可以“正确”使用而不会感到沮丧的语言
  • 获取为您生成它们的工具;您仍然会有标题,但您可以节省一些打字工作

回答by Daniel Daranas

In his article Simple Support for Design by Contract in C++, Pedro Guerreiro stated:

Pedro Guerreiro在他的文章Simple Support for Design by Contract in C++ 中说:

Usually, a C++ class comes in two files: the header file and the definition file. Where should we write the assertions: in the header file, because assertions are specification? Or in the definition file, since they are executable? Or in both, running the risk of inconsistency (and duplicating work)? We recommend, instead, that we forsake the traditional style, and do away with the definition file, using only the header file, as if all functions were defined inline, very much like Java and Eiffel do.

This is such a drastic change from the C++ normality that it risks killing the endeavor at the outset. On the other hand, maintaining two files for each class is so awkward, that sooner or later a C++ development environment will come up that hides that from us, allowing us to concentrate on our classes, without having to worry about where they are stored.

通常,C++ 类包含两个文件:头文件和定义文件。我们应该在哪里写断言:在头文件中,因为断言是规范?或者在定义文件中,因为它们是可执行的?或者两者兼而有之,冒着不一致(和重复工作)的风险?相反,我们建议我们放弃传统风格,去掉定义文件,只使用头文件,就好像所有函数都是内联定义的,非常像 Java 和 Eiffel 所做的。

这与 C++ 常态相比发生了如此巨大的变化,以至于它在一开始就冒着扼杀努力的风险。另一方面,为每个类维护两个文件是如此尴尬,迟早会出现一个 C++ 开发环境,它会隐藏我们,让我们专注于我们的类,而不必担心它们的存储位置。

That was 2001. I agreed. It is 2009 now and still no "development environment that hides that from us, allowing us to concentrate on our classes" has come up. Instead, long compile times are the norm.

那是 2001 年。我同意了。现在是 2009 年,仍然没有“开发环境对我们隐藏,让我们专注于我们的课程”。相反,长编译时间是常态。



Note:The link above seems to be dead now. This is the full reference to the publication, as it appears in the Publicationssection of the author's website:

注意:上面的链接现在似乎已经失效。这是对该出版物的完整参考,如作者网站的“出版物”部分所示:

Pedro Guerreiro, Simple Support for Design by Contract in C++, TOOLS USA 2001, Proceedings, pages 24-34, IEEE, 2001.

Pedro Guerreiro,C++ 中合同设计的简单支持,TOOLS USA 2001,Proceedings,第 24-34 页,IEEE,2001。

回答by Nils Pipenbrinck

There is no practical way to get around headers. The only thing you could do is to put all code into one big c++ file. That will end up in an umaintainable mess, so please don't do it.

没有实用的方法来绕过标题。您唯一能做的就是将所有代码放入一个大的 C++ 文件中。这最终会导致一团糟,所以请不要这样做。

At the moment C++ header-files are a nessesary evil. I don't like them, but there is no way around them. I'd love to see some improvements and fresh ideas on the problem though.

目前,C++ 头文件是必不可少的。我不喜欢他们,但没有办法绕过他们。不过,我很乐意看到有关该问题的一些改进和新想法。

Btw - once you've got used to it it's not thatbad anymore.. C++ (and any other language as well) has more anoying things.

顺便说一句 - 一旦你习惯了它就不再那么糟糕了.. C++(以及任何其他语言)有更多烦人的事情。

回答by T.E.D.

What I have seen some people like you do is write everythingin the headers. That gives your desired property of only having to write the method profiles once.

我见过一些像你这样的人所有的东西都写在标题中。这提供了您所需的属性,只需编写一次方法配置文件。

Personally I think there are very good reasons why it is better to separate declaration and definition, but if this distresses you there is a way to do what you want.

我个人认为有很好的理由为什么最好将声明和定义分开,但是如果这让您感到困扰,那么有一种方法可以做您想做的事。

回答by 0scar

There's header file generation software.I've never used it, but it might be worth looking into. For instance, check out mkhdr! It supposedly scans C and C++ files and generates the appropriate header files.

有头文件生成软件。我从未使用过它,但它可能值得研究。例如,查看mkhdr!它应该扫描 C 和 C++ 文件并生成适当的头文件。

(However, as Richard points out, this seems to limit you from using certain C++ functionality. See Richard's answer instead here right in this thread.)

(但是,正如 Richard 指出的那样,这似乎限制了您使用某些 C++ 功能。请在此线程中查看 Richard 的回答。)

回答by C?t?lin Piti?

You have to write function declarationtwice, actually (once in header file, once in implementation file). The definition (AKA implementation) of the function will be written once, in the implementation file.

实际上,您必须编写两次函数声明(一次在头文件中,一次在实现文件中)。函数的定义(AKA 实现)将在实现文件中写入一次。

You can write all the code in header files (it is actually a very used practice in generic programming in C++), but this implies that every C/CPP file including that header will imply recompilation of the implementation from those header files.

您可以在头文件中编写所有代码(这实际上是 C++ 泛型编程中非常常用的做法),但这意味着每个包含该头文件的 C/CPP 文件都意味着从这些头文件中重新编译实现。

If you are thinking to a system similar to C# or Java, it is not possible in C++.

如果您正在考虑类似于 C# 或 Java 的系统,则在 C++ 中是不可能的。

回答by Kieveli

Actually... You can write the entire implementation in a file. Templated classes are all defined in the header file with no cpp file.

实际上...您可以将整个实现写在一个文件中。模板类都定义在头文件中,没有 cpp 文件。

You can also save then with whatever extensions you want. Then in #include statements, you would include your file.

您还可以使用您想要的任何扩展名保存。然后在#include 语句中,您将包含您的文件。

/* mycode.cpp */
#pragma once
#include <iostreams.h>

class myclass {
public:
  myclass();

  dothing();
};

myclass::myclass() { }
myclass::dothing()
{
  // code
}

Then in another file

然后在另一个文件中

/* myothercode.cpp */
#pragma once
#include "mycode.cpp"

int main() {
   myclass A;
   A.dothing();
   return 0;
}

You may need to setup some build rules, but it should work.

您可能需要设置一些构建规则,但它应该可以工作。

回答by Contango

Nobody has mentioned Visual-Assist X under Visual Studio 2012 yet.

还没有人提到 Visual Studio 2012 下的 Visual-Assist X。

It has a bunch of menus and hotkeys that you can use to ease the pain of maintaining headers:

它有一堆菜单和热键,您可以使用它们来减轻维护标题的痛苦:

  • "Create Declaration" copies the function declaration from the current function into the .hpp file.
  • "Refactor..Change signature" allows you to simultaneously update the .cpp and .h file with one command.
  • Alt-O allows you to instantly flip between .cpp and .h file.
  • “创建声明”将函数声明从当前函数复制到 .hpp 文件中。
  • “重构..更改签名”允许您使用一个命令同时更新 .cpp 和 .h 文件。
  • Alt-O 允许您立即在 .cpp 和 .h 文件之间切换。