Two basic coding style patterns are possible:
- Class declarations in headers, member function/static data instantiation in .cpp files.
- Class definitions with in-line implementation in headers
Option 2 may lead to code bloat since if you use the class in multiple compilation units you may get multiple copies of the implementation in the final link; it is down to the linker to eradicate this and it may or may not do so - YMMV. It also allows users of the class access to the implementation, which may be undesirable in some cases.
A combination of the two with simple getter/setter functions in-lined and larger code bodies in separate compilation units is an option. Often if I have a constructor that is entirely implemented by the initialiser list, I will include its empty body in-line.
Example for class cExampleClass
:
cExampleClass.h
class cExampleClass
{
public:
cExampleClass() ;
~cExampleClass() ;
void memberfn() ;
} ;
cExampleClass.cpp
cExampleClass::cExampleClass()
{
// body
}
cExampleClass::~cExampleClass()
{
// body
}
void cExampleClass::memberfn()
{
// body
}
or in-lined:
cExampleClass.h
class cExampleClass
{
public:
cExampleClass()
{
// body
}
~cExampleClass()
{
// body
}
void memberfn()
{
// body
}
} ;
In both cases any source file that then uses cExampleClass
simply includes the cExampleClass.h, and cExampleClass.cpp (if it exists) is separately compiled and linked.
Note that if the class includes static data member variables, these must be instantiated in a separate compilation unit in order for there to be just one common instance. Example:
cExampleClass.h
class cExampleClass
{
public :
static int staticmember ;
} ;
cExampleClass.cpp
int cExampleClass::staticmember = 0xffff ;