Reputation: 17486
I have a question about the relationship between header and implementation files in C++.
I have received two empty header files and one empty implementation file. When I say "empty" I mean that the files only contain method declarations; I have to implement the code inside each method. (I thought that posting the code for the three files would be redundant, since they only contain declarations..)
The three files are:
interface_complexmutex.h
complexmutex.h
complexmutex.cpp
interface_complexmutex.h
has virtual methods for complexmutex
. Also, the complexmutex
class inherits from interface_complexmutex
.
These files have basic mutex functions that I have to implement. I have 2 questions:
Why do I need interface_complexmutex.h
? It does not really have a .cpp
file, and the entire implementation will be in complexmutex
files, right?
How should I include these files and use complexmutex
class in a program? (if I have the init()
method in complexmutex.cpp
, for example)
Should main.cpp
look like this?
#include <stdlib.h>
#include <stdio.h>
#include "interface_complexmutex.h"
#include "complexmutex.h"
using namespace std;
int main(){
complexmutex a;
/* do something with mutex to test */
return 0;
}
I made my own Makefile, and the code above seems to run fine so far.
Upvotes: 0
Views: 653
Reputation: 4795
Interfaces classes (C++ classes with all virtual functions) aid in reuse of interface design. These classes ideally capture only interface and not the implemenation. Hence they have only .h file and not corresponding .cpp file.
Coming to issue of re-use, suppose we need to define another mutex class, with completely different implemenation. We will not be able to re-use complexmutex class implementation but still be able to re-use interface_complexmutex class. Plus, objects of new mutex class can be used in place of complexmutex, as they have common interface.
Upvotes: 1
Reputation: 8431
1) You need an interface only if it is likely that the implementation will change later on. That will leave you free to make all the changes you want to the internals of your code without impacting the people using it to create software. That means that the users should only see the interface class and never the implementation.
To do that you'll need to implement what is called a factory
pattern. This is a function that will create an instance of the implementation class and return it as a pointer (or reference) to the interface class. You probably can write that function as a static method of your interface class.
2) In a program you should image you are the user of your code. The user doesn't care how you implement your feature, so it should not use the implementation at all. If possible it should only include the interface header and call the factory method like this:
#include "interface_complexmutex.h"
using namespace std;
int main(...) {
interface_complemutex* mutex = interface_complexmutex::create_new(...);
// do something interesting with the mutex
}
In this example, create_new
is your factory method. You can have parameters for it (usually an enumeration) if you have different implementations.
When using interfaces (actually abstract classes in C++), you need to use pointers or references. You can't create values for abstract classes. Of course, if you write test code, it's a bit different because test code is not meant to be seen/used by the users of your library.
Notes:
Let me point out that the naming is quite bad. The interface should be named complexmutex
and the implementation complexmutex_impl
since users should use the interface more, its name should be shorter (and you can replace the "impl" by something relevant such as "pthread" if you use pthreads to implement your mutex class.
As a PS note, in C++0x there is a thread library including mutex available. It is supported by some compilers already.
Upvotes: 2