tags:

views:

271

answers:

6

Most C++ class method signatures are duplicated between the declaration normally in a header files and the definition in the source files in the code I have read. I find this repetition undesirable and code written this way suffers from poor locality of reference. For instance, the methods in source files often reference instance variables declared in the header file; you end up having to constantly switch between header files and source files when reading code.

Would anyone recommend a way to avoid doing so? Or, am I mainly going to confuse experienced C++ programmers by not doing things in the usual way?

See also Question 538255 C++ code in header files where someone is told that everything should go in the header.

+4  A: 

Don't break with convention. In the end, you will make a ball of worms that doesn't work very well. Plus, compilers will hate you. C/C++ are setup that way for a reason.

Daniel A. White
Yep, that's my gut feeling as well. I'm curious whether anyone will volunteer another view.
Dickon Reed
C++'s separation of header and implementation is an archaic relic from the times when compiling relatively simple programs could take a very long time (I once worked on a system that took over 12 hours to build from scratch). But, that's how it's done, and you should generally use tools the way they are designed to be used.
Kristopher Johnson
A: 

Virtually the entire Boost library is written in header-only style. Personally I write virtually all of my C++ code in headers only, because I use lots of small objects and functions. It annoys some experienced C++ developers, but it significantly reduces the amount of code that I have to write and maintain. It also is not a problem for people with a Java or C# background.

Postscript: My score just is now down to -10! I guess this StackOverflow's way of maintaining the karmic balance of the universe.

So I'm re-thinking my recommendation to you on header-only code. I would suggest it only if you write code like me or the Boost library. That is to say code which uses templates heavily, has lots of small classes with lots of small functions, and very few translation units.

cdiggins
Boost gets away with that because almost everything in Boost is a template
Charles Salvia
This is a way of making your compilations VERY slow and ought to be avoided whenever possible in C++.
Goz
It's only slow if you also include the code in a lot of different translation units. If most of your code is header-only, then you might be able to get away with very few translation units, and then compile times might actually end up benefiting.
jalf
Is there a badge for accepting the most down voted answer?
Martin York
Yes but it brings out one of my pet peaves of Java and C#. That you can't read the interface of the class directly from the source. You basically have to read the interface from generated documentation and hope it is upto data (or generate your own). Admittedily the advancement of editors has helped devs that use bad editors by allowing code folding but it is still a pain. Preferably use a good editor and the having multiple files open simultaniously is not a problem.
Martin York
I have never had a problem with slow compilation times. I use very few translation units and lots of templates.
cdiggins
There are certainly lots of code bases that would benefit from more interface abstractions, and that's a different trade off that might cause sensibly cause repetition of some declarations. Separating class declaration and definition can get that to a limited extent.
Dickon Reed
+9  A: 
Crashworks
Interesting how this answer has been upvoted several times, while cdiggins's similar answer got downvoted.
Kristopher Johnson
Probably because he says it is a good idea and I say it is a bad idea.
Crashworks
+7  A: 

I assume you're talking about member function declarations in a header file and definitions in source files?

If you're used to the Java/Python/etc. model, it may well seem redundant. In fact, if you were so inclined, you could define all functions inline in the class definition (in the header file). But, you'd definitely be breaking with convention and paying the price of additional coupling and compilation time every time you changed anything minor in the implementation.

C++, Ada, and other languages originally designed for large scale systems kept definitions hidden for a reason--there's no good reason that the users of a class should have to be concerned with its implementation, nor any reason they should have to repeatedly pay to compile it. Less of an issue nowadays with faster systems, but still relevant for really large systems. Additionally, TDD, stubbing and other testing strategies are facilitated by the isolation and quicker compilation.

Drew Hall
Yes, I've edited the question text to clarify that I'm talking about the duplication between method declarations and definitions.
Dickon Reed
+1  A: 

You "can" get around the problem. You define an abstract interface class that only contains the pure virtual functions that an outside application will call. Then in the CPP file you provide the actual class that derives from the interface and contains all the class variables. You implement as normal now. The only thing this requires is a way to instantiate the derived implementation class from the interface class. You could do that by providing a static "Create" function that has its implementation in the CPP file.

ie

InterfaceClass* InterfaceClass::Create()
{
     return new ImplementationClass;
}

This way you effectively hide the implementation from any outside user. You can't, however, create the class on the stack only on the heap ... but it does solve your problem AND provides a better layer of abstraction. In the end though if you aren't prepared to do this you need to stick with what you are doing.

Goz
+1  A: 

C++ language supports function overloading, which means that the entire function signature is basically a way to identify a specific function. For this reason, as long as you declare and define function separately, there's really no redundancy in having to list the parameters again. More precisely, having to list the parameter types is not redundant. Parameters names, on the other hand, play no role in this process and you are free to omit them in the declaration (i.e in the header file), although I belive this limits readability.

AndreyT