Do you really need a logger in your geometry module? Always ask "do I need really A in B?" to determinate if the coupling of two modules is reasonable.
There are multiple ways to remove the dependencies between your two modules.
Does the geometry class really need a logger? No, it only logs fatal error.
Then throw an exception in case you have a fatal error, catch it and log it in the higher level code. This makes the geometry fully independent to the logger or any other module.
Does the geometry class really need a logger? Maybe, I write a bunch of diagnostic information.
How about you define a fully virtual interface (abstract base class) for the logger. This will only introduce a dependency to the header. You need only the header of the interface but not the entire module. If the pointer to the logger is NULL, just don't log anything.
How about you define any function writing diagnostic information taking a ostream
. Like this you can catch all information and log it in a higher level. This allows you to pass a stringstream or cout and increases your flexibility. The only dependency in one you already have, the C++ standard library.
How about you define the setLogger, not as taking an object, but a std::function
. For example:
class GerometryBase
{
public:
void setLogger(std::function<void (const std::string&)> value)
{
logger = value;
}
private:
std::function<void (const std::string&)> logger;
void log(const std::string& msg)
{
if (logger)
{
logger(msg);
}
}
}
To bind the logger to the geometry classes:
Logger logger;
Box box;
box.setLogger([&] (const std::string& msg) {
logger.log(msg);
});
There are many ways you can reduce coupling between modules. You just have to think about it for a while. Going over the standard library is my favorite way, it is standard for a good reason. Since C++11 introduced lambdas, coupling in my modules has significantly decreased.