Can I write C ++ code without headers (declarations of duplicate functions)?

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

+46
c ++ header-files header
Jun 16 '09 at 13:55
source share
23 answers

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

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

Update 150120:

The new C ++ syntax '11 / 14 can only be used in lzz function bodies.

+54
Jun 16 '09 at 14:18
source share

I felt the same way when I started writing C, so I also learned this. The answer is that yes, it is possible and no, you do not want.

First, yes.

In GCC, you can do this:

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

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

Then with no:

This only works if the compiler has access to the entire source. You cannot use this trick when writing the library you want to distribute, but keep the source private. Either you distribute the full .cph file, or you need to write a separate .h file to go with your .lib. Although, perhaps you can automatically generate it using a macro preprocessor. However, it will be hairy.

And reason number 2, why you do not want this, and this is probably the best: compilation speed. Typically, C source files need to be recompiled only when the file itself changes or in any of the files that include the changes.

  • A C file can change frequently, but a change only involves recompiling a single changed file.
  • Header files define interfaces, so they should not change so often. However, when they do this, they start recompiling each source file that includes them.

When all your files are combined into a header and source files, each change will result in recompilation of all source files. C ++ is not known for its fast compilation times even now, imagine what happens when an entire project needs to be recompiled every time. Then extrapolate this to a project of hundreds of source files with complex dependencies ...

+36
Jun 16 '09 at 14:12
source share

Sorry, but there is no such thing as “best practice” for removing headers in C ++: this is a bad idea, period. If you hate them so much, you have three options:

  • Take a close look at the internal components of C ++ and any compilers that you use; you will encounter different problems than the average C ++ developer, and you may have to solve them without much help.
  • Select a language that you can use "on the right" without receiving a click.
  • Get a tool to create them; you will still have headlines, but you will save some typing efforts.
+25
Jun 16 '09 at 14:07
source share

There is no practical way to get around the headlines. The only thing you could do is put all the code in one big C ++ file. This will end in a useless mess, so please do not do this.

At the moment, C ++ header files are a sharp evil. I do not like them, but they are not around. I would like to see some improvements and fresh ideas on this issue.

Btw - once you get used to it, it's not that bad anymore .. C ++ (and any other language) also has more unpleasant things.

+9
Jun 16 '09 at 13:59
source share

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

Typically, a C ++ class consists of two files: a header file and a definition file. Where should we write statements: in the header file, because statements are a specification? Or in the definition file, as they are being executed? Or in both, does the risk of inconsistency (and duplicate work) work? We recommend that instead we leave the traditional style, and end the definition file using only the header file, as if all the functions were defined inline, very similar to Java and Eiffel.

It’s such a drastic change in the normality of C ++ that there are risks associated with sideways. On the other hand, maintaining two files for each class is inconvenient, which sooner or later the C ++ development environment hides from us, which allows us to focus on our classes without worrying about where they are stored.

It was the year 2001. I agreed. Now is the year 2009, and there is still no "development environment that hides from us, which allows us to focus on our classes." Instead, long compilation times are the norm.

Fortunately, we now have C # where we cannot use header files ... and long compilation times :)




Note. . Now the link above is dead. This is a complete publication link, as shown in the Publications section of the author ’s website :

Pedro Guerreiro, Simple design support for C ++ contract, TOOLS USA 2001, Proceedings, pages 24-34, IEEE, 2001.

+9
Jun 16 '09 at 14:10
source share

What I saw, people like you write everything in the headlines . This gives you the desired property to only write method profiles once.

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

+8
Jun 16 '09 at 14:07
source share

You must write the function Ad twice, in fact (once in the header file, once in the implementation file). The definition (AKA implementation) of the function will be written once in the implementation file.

You can write all the code in the header files (this is actually a very practical practice in general C ++ programming), but this means that every C / CPP file, including this header, will imply recompiling the implementation from these header files.

If you are thinking of a system like C # or Java, this is not possible in C ++.

+5
Jun 16 '09 at 13:59
source share

This software is for creating header files. I have never used it, but it might be worth a peek into it. For example, check mkhdr ! It supposedly scans C and C ++ files and generates corresponding header files.

(However, as Richard points out, this seems to limit the use of certain C ++ functions. See instead here in this section .)

+5
Jun 16 '09 at 14:17
source share

Actually ... You can write the entire implementation in a file. Template classes are defined in a header file without a cpp file.

You can also save all the necessary extensions. Then in the #include statements you must include your file.

 /* 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 set some build rules, but it should work.

+3
Jun 16 '09 at 14:03
source share

You can avoid headings. Completely. But I do not recommend this.

You will come across some very specific limitations. One of them is that you cannot have circular links (you cannot have a Parent class containing a pointer to an instance of the ChildNode class, and the ChildNode class also contains a pointer to an instance of the Parent class. 'Must be one or another.)

There are other limitations that ultimately make your code really weird. Stick to the headlines. You will learn how to really like them (since they give a good overview of what the class can do).

+2
Jun 16 '09 at 14:26
source share

To suggest a variant on the popular rix0rrr answer:

 // foo.cph #define INCLUDEMODE #include "foo.cph" #include "other.cph" #undef INCLUDEMODE void foo() #if !defined(INCLUDEMODE) { printf("Hello World!\n"); } #else ; #endif void bar() #if !defined(INCLUDEMODE) { foo(); } #else ; #endif 

I do not recommend this, bit, I think this design demonstrates the removal of repetition of content due to repetition of the company. Perhaps this makes it easier to copy pasta? This is not really a virtue.

As with all other tricks of this kind, modifying the function body will still require recompiling all the files, including the file containing this function. Very careful automatic tools can partially avoid this, but they still have to analyze the source file for verification and be carefully designed so as not to overwrite their output if it is no different.

For other readers: I spent a few minutes trying to figure out how to turn on the guards in this format, but didn't come up with anything good. Comments?

+2
Jun 17 '09 at 3:52
source share

After reading all the other answers, I find it missing that work continues on adding module support to the C ++ standard. This will not be done for C ++ 0x, but the intention is that it will be considered in a later technical review (and not in anticipation of a new standard that will take a lot of time).

Proposal that was discussed, N2073 .

The bad part of this is that you will not get this, even with the latest C ++ 0x compilers. You will have to wait. At the same time, you will have to compromise between the uniqueness of the definitions in the header-only libraries and the cost of compilation.

+2
Mar 16 2018-11-11T00:
source share

No one has mentioned Visual-Assist X in Visual Studio 2012 yet.

It has many menus and hotkeys that you can use to ease the pain of maintaining headings:

  • Create Declaration copies the function declaration from the current function to the .hpp file.
  • "Refactor..Change signature" allows you to simultaneously update .cpp and .h files with a single command.
  • Alt-O allows you to instantly switch between .cpp and .h files.
+2
Jun 01 '13 at 14:48
source share

As far as I know, no. Headings are an integral part of C ++ as a language. Remember that the forward declaration allows the compiler to simply include a function pointer on the compiled object / function without having to include the entire function (which you can bypass by declaring the inline function (if the compiler feels like this).

If you really hate creating headers, write a perl-script to auto-generate them. I am not sure what I recommend.

+1
Jun 16 '09 at 14:02
source share

You can do without headings. But why waste effort trying to avoid the carefully developed best practices that have been developed over the years by experts.

When I wrote basic, I liked the line numbers. But I would not think that you are trying to drive them into C ++, because it is not C ++. The same goes for headings ... and I'm sure the other answers explain all the reasoning.

+1
Jun 16 '09 at 14:17
source share

I understand your concerns. I would say that the main problem with C ++ is the compilation / assembly method that he inherited from C. The C / C ++ header structure was developed at a time when coding included fewer definitions and more implementations. Don’t throw bottles at me, but what it looks like.

Since then, the PLO has conquered the world, and the world more describes definitions and then implementation. As a result, including headers, it is very painful to work with a language in which fundamental collections, such as those in STL, are made with templates that are known to be difficult for the compiler. All these magic with precompiled headers does not help so much when it comes to TDD, refactoring tools, general development environment.

Of course, C programmers do not suffer too much from this, since they do not have header files with a compiler and are therefore happy with the fairly simple, low-level chain of compilation tools. With C ++, this is a story of suffering: endless forward declarations, precompiled headers, external parsers, custom preprocessors, etc.

Many people, however, do not understand that C ++ is ONLY a language that has strong and modern solutions for high and low level problems. It is easy to say that you should go to another language with the correct reflection and assembly system, but it does not make sense that we should sacrifice low-level software solutions with this, and we need to complicate the situation using a low-level language with some virtual machine / JIT based solution .

I have had this idea for some time, which would be the coolest thing on earth to have a “single” tool-based C ++ chain, similar to the one in D. The problem is with the cross-platform part: object files can store any information, no problems with this, but since the structure of the file structure on the windows is different from the ELF structure, it would be painful in the ass to implement a cross-platform solution for storing and processing a partial compilation unit.

+1
Sep 14 '10 at
source share

Completely can be developed without header files. A direct may include the source file:

 #include "MyModule.c" 

The main problem with this is one of the circular dependencies (i.e.: in C, you must declare a function before calling it). This is not a problem if you develop your code completely from top to bottom, but it may take some time to wrap them around such a design template if you are not used to it.

If you absolutely must have circular dependencies, you might consider creating a file specifically for announcements and including it in front of everything else. This is a bit inconvenient, but still less pollution than having a header for each C file.

I am currently developing this method for one of my major projects. Here is a brief overview of the benefits that I have experienced:

  • Significantly less file pollution in the source tree.
  • Faster assembly time. (Only one object file is created by the compiler, main.o)
  • More simple files. (Only one object file is created by the compiler, main.o)
  • No need to “clean”. Each assembly is "clean."
  • Less boiler plate code. Less code = less potential errors.

I found that Guiche (Cryptic Sea game, Edmund Macmillen) used a variation of this technique in his own source code.

+1
Mar 16 '11 at 8:19
source share

You can carefully lay out your functions so that all dependent functions are compiled after their dependencies, but, as Niels implied, this is not practical.

Catalin (to forgive missing diacritics) also suggested a more practical alternative to defining your methods in header files. This can work in most cases, especially if you have defenders in the header files to make sure they are included only once.

I personally believe that header files + declaring functions are much more desirable in order to “get your head around” the new code, but this is a personal preference, I suppose ...

0
Jun 16 '09 at 14:03
source share

For practical purposes, no, this is impossible. Technically, yes you can. But honestly, this is an abuse of the language, and you must adapt to the language. Or go to something like C #.

0
Jun 16 '09 at 14:17
source share

It is best to use header files, and after a while it will grow in you. I agree that having only one file is easier, but it can also lead to poor coding.

some of these things, althoug feel awkward, allow you to get more than what gets in your eyes.

as an example, think of pointers, pass parameters by value / by reference ... etc.

for me, header files let me structure my projects correctly

0
Jun 16 '09 at 15:40
source share

Learn to recognize that header files are a good thing. They separate how codes are displayed to another user from the implementation of how he actually performs his operations.

When I use someone else's code, I now want to go through the entire implementation to see that the methods are in the class. I care about what the code does, not how it does it.

0
Jun 21 '09 at 17:37
source share

It was “reborn” thanks to a duplicate ...

In any case, the concept of the header is decent, that is, it separates the interface from the implementation details. The header describes how you use the class / method, and not how it does it.

The disadvantage is the detail inside the headers and all the necessary workarounds. These are the main problems that I see in them:

  • dependency generation. When the header is changed, any source file that includes this header requires recompilation. Of course, the problem is which source files actually use it. When a clean build is performed, it is often necessary to cache information in some dependency tree later.

  • turn on the guards. Well, we all know how to write them, but in an ideal system this would not be necessary.

  • personal data. Inside the class, you must put personal data in the header. Yes, the compiler must know the "size" of the class, but on an ideal system, it will be able to link this at a later stage. This leads to all kinds of solutions, for example pImpl, and uses abstract base classes, even if you only have one implementation just because you want to hide the dependency.

An ideal system will work with

  • definition and declaration of a separate class
  • A clear link between the two so that the compiler knows where the class declaration and its definition is declared, and will know what class size is.
  • You declare using class , not #include preprocessor. The compiler knows where to find the class. After you have completed the “use of the class”, you can use this class name without qualifying it.

I would be interested to know how D. does it.

Regarding the use of C ++ without headers, I would say that you do not need these abstract base classes and the standard library. , , , .

0
16 . '11 11:47
source share

header file , c++ file .

header file , c++ file , . , header , code file .

header file c++ file :

 #pragma once #include <windows.h> static class ConsoleUtils { public: static BOOL SetConsoleDisplayMode(HANDLE hOutputHandle, DWORD dwNewMode) { typedef BOOL(WINAPI *SCDMProc_t) (HANDLE, DWORD, LPDWORD); SCDMProc_t SetConsoleDisplayMode; HMODULE hKernel32; BOOL bFreeLib = FALSE, ret; const char KERNEL32_NAME[] = "kernel32.dll"; hKernel32 = GetModuleHandleA(KERNEL32_NAME); if (hKernel32 == NULL) { hKernel32 = LoadLibraryA(KERNEL32_NAME); if (hKernel32 == NULL) return FALSE; bFreeLib = true; } SetConsoleDisplayMode = (SCDMProc_t)GetProcAddress(hKernel32, "SetConsoleDisplayMode"); if (SetConsoleDisplayMode == NULL) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); ret = FALSE; } else { DWORD tmp; ret = SetConsoleDisplayMode(hOutputHandle, dwNewMode, &tmp); } if (bFreeLib) FreeLibrary(hKernel32); return ret; } }; 
-2
24 . '16 14:51
source share



All Articles