10

I have a homework assignment and I need to evaluate which approach is better according to GRASP "Protected Variation". I found a question on Stack Overflow about the separation of header and code files in C++.

However, what I want to know why Java does not follow C++ in promoting the separation of class declarations and class definitions. Are there any advantages with the Java method, over the C++ method?

9
  • If you want to ask "Why doesn't Java use header files", then just ask that and do away with the "which is better" stuff - as you've seen, we're allergic to that ;) Also search, I'm pretty certain this (or at least closely related questions) have been brought up before.
    – user7043
    Commented Nov 8, 2011 at 17:09
  • oops, the link didn't work. I'll reformulate, what I wanted to know basically, is the differences between both of them and which one tends to be more easy to reuse the code or for extensibility. Commented Nov 8, 2011 at 17:11
  • 1
    C (and by extension C++) really had no choice but to separate the header files from the implementation files, due to the limited one-pass compiler technology at the time C was created.
    – Channel72
    Commented Nov 8, 2011 at 17:11
  • 2
    Java can have Interfaces which can separate class definition and class implementation, if the class in question implements the interface. Not quite the same as C++ though. Commented Nov 8, 2011 at 17:22
  • 1
    Also, C++ header files expose considerably more implementation than I like, unless you use the PIMPL idiom. It's necessary to list all the data members, even if private, so the implementation will know the size, and the private member functions also. Commented Nov 8, 2011 at 17:31

5 Answers 5

14

How many lines of code are in the following program?

#include <iostream>

int main()
{
   std::cout << "Hello, world!\n";
   return 0;
}

You probably answered 7 (or 6 if you didn't count the blank line, or 4 if you didn't count the braces).

Your compiler, however, sees something very different:

~$ cpp hello.cpp | wc
  18736   40822  437015

Yes, that's 18.7 KLOC just for a "Hello, world!" program. The C++ compiler has to parse all that. This is a major reason why C++ compilation takes so long compared to other languages, and why modern languages eschew header files.

A better question would be

Why does C++ have header files?

C++ was designed to be a superset of C, so it had to keep header files for backwards compatibility.

OK, so why does C have header files?

Because of its primitive separate compilation model. The object files generated by C compilers don't include any type information, so in order to prevent type errors you need to include this information in your source code.

~$ cat sqrtdemo.c 
int main(void)
{
    /* implicit declaration int sqrt(int) */
    double sqrt2 = sqrt(2);
    printf("%f\n", sqrt2);
    return 0;
}

~$ gcc -Wall -ansi -lm -Dsqrt= sqrtdemo.c
sqrtdemo.c: In function ‘main’:
sqrtdemo.c:5:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
sqrtdemo.c:5:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
~$ ./a.out 
2.000000

Adding the proper type declarations fixes the bug:

~$ cat sqrtdemo.c 
#undef printf
#undef sqrt

int printf(const char*, ...);
double sqrt(double);

int main(void)
{
    double sqrt2 = sqrt(2);
    printf("%f\n", sqrt2);
    return 0;
}

~$ gcc -Wall -ansi -lm sqrtdemo.c
~$ ./a.out 
1.414214

Notice that there are no #includes. But when you use a large number of external functions (which most programs will), manually declaring them gets tedious and error-prone. It's much easier to use header files.

How are modern languages able to avoid header files?

By using a different object file format that includes type information. For example, the Java *.class file format includes "descriptors" that specify the types of fields and method parameters.

This was not a new invention. Earlier (1987), when Borland added separately-compiled "units" to Turbo Pascal 4.0, it chose to use a new *.TPU format rather than Turbo C's *.OBJ in order to remove the need for header files.

1
  • Although interestingly, I'm fairly sure that you could set Turbo Pascal to output OBJ files rather than TPUs...
    – user
    Commented Nov 9, 2011 at 12:33
7

Java has interfaces to define a contract. This gives a higher level of abstraction from what the caller needs and the actual implementation. i.e. the caller doesn't need to know the implementing class, it only needs to know the contract it supports.

Say you want to write a method which slows all the key/values in a Map.

public static <K,V> void printMap(Map<K,V> map) {
    for(Entry<K,V> entry: map.entrySet())
        System.out.println(entry);
}

This method can call entrySet() on an abstract interface which is removed from the class implementing it. You can call this method with.

printMap(new TreeMap());
printMap(new LinkedHashMap());
printMap(new ConcurrentHashMap());
printMap(new ConcurrentSkipListMap());
5
  • 1
    Welcome to Programmers there Peter - thought I recognized the name :-). I'll add that some people will argue that Abstract base classes in Java also define a contract - but that's probably an argument for a separate thread. Commented Nov 8, 2011 at 22:26
  • Hello @MartijnVerburg, Nice addition. I think abstract classes blur the distinction between interfaces without implementations and concrete classes. Extension methods will blur the distinction even further. I tend to prefer to use an interface if I can as they are simpler. Commented Nov 8, 2011 at 22:39
  • Yeah Java is going to start heading down the Scala path of having multiple ways to define a public contract - I'm not sure that's a good thing or not yet :-) Commented Nov 9, 2011 at 9:26
  • -1 This is possible in C++ as well, with a simple #define interface class.
    – Sjoerd
    Commented Nov 9, 2011 at 13:06
  • @Sjoerd I didn't know C++ methods no longer need to use the virtual keyword to get polymorphism and this has no performance penalty if you only use one or two concrete types, like they are in Java. Can you point me to any documentation on how this works in C++? Commented Nov 9, 2011 at 13:56
6

Headers exist, quite frankly, as a historical accident. It's an incredibly poor system, no other language has anything so terrible, and anyone who doesn't have to deal with them should rejoice.

3

Headers are there to enable separate compilation. By #including the headers, the compiler doesn't need to know anything about the binary structure of compiled C++ code, and can leave that job to a separate linker. Java does not use a separate linker with its compiler, and since .class files are strictly defined, the compiler is able to read them to determine all their members with all their types, without any need to re-declare them in each compilation unit.

You can include all the implementation in a C++ header, but it causes the compiler to recompile it every time it's #included, forcing the linker to sort out and discard the duplicate copies.

0

Java does promote the separation of class definition and implementation, it just depends where you're looking from.

When you're the author of a Java class you get to see the definition of the class as well as its implementation in one file. This simplifies the development process as you've only gor to go to one place to maintain the class, you don't have to switch between two files (.h and .cpp as you would in C++). However, when you're the consumer of the class you only deal with the definition, via a .class file that is either packaged in a .jar or a standalone .class

C++ allows you to separate the definition and implementation, but it's ad-hoc. For example, there's nothing to stop you writing the method inline within the header file, and for template classes this is mandatory. The header file also lists out any member variables, which are visible to anyone who looks at the header file, even though they're an implementation detail of the class and irrelevant to a consumer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.