Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

(*.h and *.cpp) vs. (only *.cpp)? 1

Status
Not open for further replies.

vladibo

Programmer
Sep 14, 2003
161
CA
Sorry guys for the dummy question, but I want to clarify this.

When I explore c++ code I see that some times it consists of deviding a class on class declaration in a header (*.h) file and class definition in *.cpp file, however sometimes I see that everything is in one (*.cpp) file the same way I would do this in Java or C#.
Then what is the right way to do this in C++ and especialy in .NET? Advantages disadvantages of different aproaches?

Thank you in advance.
 
I personally think it is mostly has to do with neatness of code. Having two separate files reduces the large amount of scrolling, and the .h file makes finding things much easier. Can you imagine a class that would be declared with all of the member functions in it! It would be quite messy. I suppose you could include the code at the bottom of the .h file, but I think making a separate file just helps searching for what you want to find much easier.

I recently made two closely related classes in the same two files. This is because I decided they would always be edited together. This was my new style. Having two separet files is simply part of the programmer's style and its effectiveness depends on the size of the program.

To me your question reminds me of the fact that we can make all of our code on one line without OOP or functions. But with experience, we all know that is (in all reality) not possible since we are human. The neater the code is the better programs we can make.

If there is another reason to why the files are separate I would learn the answer to a question I have had in the back of my mind for quite some time too!

-Bones
 
There are really two questions here, I guess:

vlabido:

Putting everything about a class into a source file (with no header file) is fine as long as that's the only place it gets used.

However, if you're going to use it in another source file, you have to copy the entire class declaration to that file so the code in that source file can compile.

In fact, that's basically what including a header file does: it copies the class declaration into each source file that includes it.


Bones3:

Yes, neatness does play a role in why you don't put everything into a header file. There's a more important reason, though.

If you put all the class code in a header file, then anytime you change that code, you'll have to recompile every file that includes it.

When you have a header file and a source file per class, if you change the code in the source file (the iplementation) but don't touch the header file (the interface), you'll just have to recompile the module you changed, then relink your project.

Compiling takes a long time compared to linking, so in large projects, it would be a very bad idea to require a recompile of the entire thing every time you made some change on a widely-used component.

Separating interface from implementation is a good idea in general.
 
Cool, that hasn't occured to me since I have never compiled a progect large enough to take more than just a minute (usually much less than that).

-Bones
 
Even if someone wants to do everything in class header files, there are some cases that make it impossible. A case that I know is mutual inclusions.
If 2 classes need each other then you are likely to implement them in implementation files. Consider this dummy example :

A.hpp :
Code:
#include "B.hpp"

class A
{
public:
  A (const B& b_object)
  {
     int a = b_object.some_bint ();
     //...
  }

  int some_aint () const
  {
     return 0;
  }
};

B.hpp :
Code:
#include "A.hpp"

class B
{
public:
  B (const A& a_object)
  {
     int b = a_object.some_aint ();
     //...
  }

  int some_bint () const
  {
     return 0;
  }
};

A.hpp et B.hpp are mutually inclusives, which leads to an infinite including loop.
The only solution I've found so far is to use both class forward declaration and implementation files.

A.hpp becomes:
Code:
class B;

class A
{
public:
  A (const B& b_object);

  int some_aint () const
  {
     return 0;
  }
};

A.cpp :
Code:
#include "A.hpp";
#include "B.hpp";

A::A (const B& b_object);
{
   int a = b_object.some_bint ();
   //...
}



B.hpp becomes:
Code:
class A;

class B
{
public:
  B (const A& a_object);

  int some_bint () const
  {
     return 0;
  }
};

B.cpp :
Code:
#include "B.hpp";
#include "A.hpp";

B::B (const A& a_object);
{
   int b = a_object.some_aint ();
   //...
}

--
Globos
 
globos,

"Mutual Inclusions" are handled by Compiler Directives.
Code:
#ifndef CLASS_A_H
#define CLASS_A_H

#include "classb.h"

class A{
blah,blah,blah
};

#endif
Do this in both header files (change CLASS_A_H to CLASS_B_H, however) and you won't have infinite inclusions... That being said, chipperMDW's comment about compiling large projects shows that separating the interface from the implementation is usually the best practice.

Ben

There's no place like 127.0.0.1.
 
benlinkknilneb,

Although I already know this technique and apply it every day, it does not solve the problem. If you try to compile the first example I gave, you will get pretty strange errors I think.
Just look deeper at the code : class A needs class B which need class A which needs class B which needs class A which ...

--
Globos
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top