3

We can include < iostream > and we do not care about its cpp file, but why can't we do the same for our own classes ?

So if my project uses 50 custom classes, not only do I have to have 50 includes, but also have to compile/link 50 cpp files along with them (and clutter the project tree).

Q: Is there any way to use custom headers the same way we use standard libraries ?

In other words is there a kosher way so that we do not have to add all those cpp files in the project. I want to only include ClassSnake.hpp which in turn knows where to find ClassSnake.cpp which links to ClassVector.hpp which knows how to find ClassVector.cpp ... all in an automatic daisy chain without me having to explicitly add those cpp files in my project tree.

Edit: I am not worried so much about the cpp files recompiling. My issue is with having to remember which class internally links to which other class, so that I can properly include all those hidden cpp files in the project tree ... and clutter the tree.

enter image description here

Thomas An
  • 503
  • 2
  • 7
  • 17
  • Basically: Make every function `inline` or `template`. This should empty your .cpp files, at which point you can delete them. Do not do this to main of course. – danielschemmel May 15 '13 at 18:52
  • 1
    @dionadar, that is not a good solution to this. Throwing all the implementation in a header file and just saying "make it template" doesn't really solve anything. – Moo-Juice May 15 '13 at 18:52
  • It will actually recompile all the code all the time because there are no separate object files anymore. All the templates will be generated in the main file. – Sarien May 15 '13 at 18:56
  • @Moo-Juice Why not? The problem with just putting everything in a header is inclusion in multiple compilation units (and rarely name clashes with elements with internal linkage). Making everything a `template` or `inline` defuses these problems. Even global variables can be dealt with like this: Create an inline function that returns a reference to a static variable... – danielschemmel May 15 '13 at 18:57
  • @MikeSeymour, yes but it also means that those header files are getting recompiled all the time, and the cpp files *shouldn't* be being recompiled all the time unless their implementation changes. It's merely moving the problem to every single other compilation unit, surely? – Moo-Juice May 15 '13 at 19:00
  • @dionadar, so every time I modify my .cpp file that references the header file, it *all* gets recompiled when the implementation doesn't need to be. – Moo-Juice May 15 '13 at 19:02
  • This is what libraries are for. Stick the source and header files in a new library project and include the necessary headers in other projects that use it. It's the `kosher` way. – Captain Obvlious May 15 '13 at 19:08
  • @Moo-Juice Yes, every time you modify it, it all gets recompiled. Just like all the standard library headers you include. – danielschemmel May 15 '13 at 19:11
  • @dionadar, except the comparison to standard libraries isn't a good one :) They are template-heavy, and header-implemented for a good reason. The OP, on the other hand, just doesn't want the Cpps in the project getting recompiled (which they shouldn't be unless changed anyway!). Sounds like a library is needed imho. – Moo-Juice May 15 '13 at 19:13
  • Let's just agree to disagree the usefulness of the technique. However, it is the valid solution to the exercise "make custom headers work like the standard library" :) – danielschemmel May 15 '13 at 19:17
  • Your toolchain should only build the cpp files that are modified or that depend on a header file that was modified. By moving code into the CPP file from the header file, you reduce the risk of cpp files being recompiled. – Thomas Matthews May 15 '13 at 19:18

6 Answers6

4

Not really.

What you're missing is that your compiler toolchain has already compiled the bits <iostream> needs that aren't in the header.

Your compiler (linker really) just implicitly links this code in without you having to specify it.

If you want to clean up your project tree a bit, you could create other projects that are libraries of code for one main project to use.

Collin
  • 11,977
  • 2
  • 46
  • 60
  • So there is no way to daisy-chain this automatically ? Have something inside the First.hpp file that looks for its First.cpp and First.cpp file includes second.hpp and third.hpp which know where to find their respective cpp files ... and trickle down automatically ? – Thomas An May 15 '13 at 19:07
  • That's a problem for your build system to solve. It looks like you're using Code::Blocks.. it should handle this correctly already. – Collin May 15 '13 at 19:15
  • I have no problem compiling the project. The issue is with the clutter created of having to include a bunch of cpp files in the project tree. (and having to remember which class links to which other class so that I can manually fish out those cpp files for inclusion, every time.) – Thomas An May 15 '13 at 19:20
  • This is sort of a fact of life programming in C++. The compiler needs to have compiled the code you're going to use. You could always create subfolders for your project and organize your code. – Collin May 15 '13 at 19:24
0

Headers do not (normally) provide implementations of things (functions, classes), they must be implemented somewhere if you are going to use them.

When you include your own header, you include your own sources in order to provide the implementation. Straight forward enough there.

When you include a standard header (such as iostream), the implementation is in the libraries you include (either implicitly because the compiler just does it, or explicitly through compiler/linker options).

mah
  • 39,056
  • 9
  • 76
  • 93
  • Any willingness to explain why this should be downvoted? I will happily fix or delete but downvoting without explanation isn't particularly helpful. – mah May 15 '13 at 18:48
  • Probably just one of the other guys that answered this question. – RandyGaul May 15 '13 at 18:49
  • @mah, having same issue, have flagged question. – Moo-Juice May 15 '13 at 18:51
  • I didn't downvote, but this doesn't answer the question... "Is there any way to use custom headers the same way we use standard libraries ?" (though it does describe some of the underlying mechanisms at play). – Chad Barth May 15 '13 at 18:52
0

As an extention to Collin's answer, you could always offload "shared" code to a shared library, and then reference the header files and lib files in your other projects. The lib files will only come in to play at the linker stage, as all those other pesky .cpp files have already been compiled.

If this is is just a self-enclosed project with no other commonality, you're just going to have to suck up the fact you have to provide an implementation :)

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
0

Actually, if you have a decent build process cpp files that have not changed will not be compiled again. They only have to be linked. If you don't want that either you need to create your own libraries. It can be done, is just a bit more involved.

Edit: This question might help you if you want to create your own library.

So answer to edited question: Yes, you can avoid having all those cpp files in the project but only if you don't want to change them. In this case you can just create a static or dynamic library and you will only need the symbols for linking. In that case you would create another project to compile everything into such a library.

Community
  • 1
  • 1
Sarien
  • 6,647
  • 6
  • 35
  • 55
0

First of all if you use a system such as make then it will identify that the .cpp file has not changed and therefore the compiler does not have to reconstruct the object file.

You can also create your own static/shared library. The method to do this depends on the platform. If you go down this avenue then all you need is the header file along with the library.

Please Google on how to construct how to make a library for you particular platform.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
-1

STL code like "iostream" is made of templates no code is actually generated until instances of the templates are created.

  • Actually you can use explicit template instantiation to generate code from a template in either a static or shared library. The compiler may still generate code for instances you create but it's usually eliminated during link time. In C++11 you can declare the template as `extern` to prevent the compiler from instantiating a template that already exists somewhere else (in a library). – Captain Obvlious May 15 '13 at 19:04
  • My answer was true in the context of the question. Explicit instantiation was not an issue. Mainly, because you have to use it "explicitly". – Manuel del Castillo May 16 '13 at 12:15
  • Sorry but your answer should have been a comment. It doesn't address the Op's actual question - how to use headers the same way the C++ standard library is used. While your description of how template code is generated is ok it does not provide or suggest any type of solution. – Captain Obvlious May 16 '13 at 13:08