In C# or Java, classes are declared and defined at the same time. In C++, the norm is to do that separately. What if we write the whole class in one , say .cpp, file and include that in files that references to it, what kinds of bad thing technically would happen besides a lengthened compilation process?
If your implementation of MyClass
is all in the header file MyClass.h
then any file you needed to implement MyClass
will be included whenever someone includes MyClass.h
.
If you change any part of MyClass.h
, even if it's trivial (such as adding a comment or even a space) then all files that include it will have to recompile, even if the interface hasn't changed.
Neither of these matters for toy projects, but as you noted, when you have a program that consists of hundreds (or thousands, etc.) of class files, the added compilation time alone makes it worthwhile to separate out implementation from interface.
For instance, if I have the following:
// MyClass.h
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
private:
// ...
};
It would more ideomatically be written as:
// MyClass.h
class Inventory;
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory);
private:
// ...
};
// MyClass.cc
#include "MyClass.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
MyClass()::MyClass()
{
}
void MyClass()::processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
Notice: Including MyClass.h
doesn't mean iostream
, iomanip
, sstream
, string
, or Inventory.h
have to be parsed. Changing how processInventory
works doesn't mean all files using MyClass.h
have to be recompiled.
Notice how much easier it can be to figure out how to use MyClass
now. Header files serve an important purpose: they show people how to use your class. With the modified MyClass.h
it's easy to see the list of functions. If each function is defined in the header, then you can't look at just the list of functions. That makes it harder to figure out how to use the class.
You may break the one definition rule.
If you write this:
class foo
{
public:
void doit();
};
foo::doit() {}
and include that in multiple classes, you will have multiple definitions of foo::doit
and your link will fail.
But if you make all your classes inline, either by defining them within the class declaration:
class foo
{
public:
void doit() {
}
};
or by explicitly making them inline:
class foo
{
public:
void doit();
};
inline void foo::doit() {}
then you can include that file as many times as you like.
The linker will see multiple definitions of the class's members when you try to combine multiple such objects. Thus, you won't be able to produce a binary from source files that include anything in more than one place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With