There is a duplicate class implementation in two projects, which are using C++. When i tried to merge the minor differences of both into a single class, i faced a blocker as the #define's in the class are having direct dependency on static object which is created out of this class on both projects as shown below.
From Project1
enum severity_type
{
debug = 1,
error,
warning
};
template< typename T >
class logger
{
public:
logger(const std::string& name);
};
#define LOGGING_LEVEL_1
static logger< file_log_policy > log_inst(GetAppDataPath()+ "\\Logs\\backup.log");
#ifdef LOGGING_LEVEL_1
#define LOG log_inst.print< severity_type::debug >
#define LOG_ERR log_inst.print< severity_type::error >
#define LOG_WARN log_inst.print< severity_type::warning >
#else
#define LOG(...)
#define LOG_ERR(...)
#define LOG_WARN(...)
#endif
#ifdef LOGGING_LEVEL_2
#define ELOG log_inst.print< severity_type::debug >
#define ELOG_ERR log_inst.print< severity_type::error >
#define ELOG_WARN log_inst.print< severity_type::warning >
#else
#define ELOG(...)
#define ELOG_ERR(...)
#define ELOG_WARN(...)
#endif
From Project 2
enum severity_type
{
debug = 1,
error,
warning
};
template< typename T >
class logger
{
public:
logger(const std::string& name);
};
#define LOGGING_LEVEL_1
static logger< file_log_policy > log_inst(GetAppDataPath()+ "\\Logs\\restore.log");
#ifdef LOGGING_LEVEL_1
#define LOG log_inst.print< severity_type::debug >
#define LOG_ERR log_inst.print< severity_type::error >
#define LOG_WARN log_inst.print< severity_type::warning >
#else
#define LOG(...)
#define LOG_ERR(...)
#define LOG_WARN(...)
#endif
#ifdef LOGGING_LEVEL_2
#define ELOG log_inst.print< severity_type::debug >
#define ELOG_ERR log_inst.print< severity_type::error >
#define ELOG_WARN log_inst.print< severity_type::warning >
#else
#define ELOG(...)
#define ELOG_ERR(...)
#define ELOG_WARN(...)
#endif
Here, you can observe as we have two static objects from two projects.
I want to have these static objects while the program is running. But the major bottle neck while i try to merge these files are the #define's from Project 1
#define LOGGING_LEVEL_1
static logger< file_log_policy > log_inst(GetAppDataPath()+ "\\Logs\\backup.log");
#ifdef LOGGING_LEVEL_1
#define LOG log_inst.print< severity_type::debug >
#define LOG_ERR log_inst.print< severity_type::error >
#define LOG_WARN log_inst.print< severity_type::warning >
#else
#define LOG(...)
#define LOG_ERR(...)
#define LOG_WARN(...)
#endif
and project2
#define LOGGING_LEVEL_1
static logger< file_log_policy > log_inst(GetAppDataPath()+ "\\Logs\\restore.log");
#ifdef LOGGING_LEVEL_1
#define LOG log_inst.print< severity_type::debug >
#define LOG_ERR log_inst.print< severity_type::error >
#define LOG_WARN log_inst.print< severity_type::warning >
#else
#define LOG(...)
#define LOG_ERR(...)
#define LOG_WARN(...)
#endif
these #define's like LOG, LOG_ERR are used in thousands of places in code. can you suggest a better approach here, without modifying the #define's where i can merge these classes and use a single class for both projects.
i want the #define's to be unchanged and the duplicate classes to be merged into one, and the static objects should also exist.
Can someone suggest a better approach where i can refactor this code without touching #define's
Restating the problem to make sure I understand: you have two separate codebases (call them backup
and restore
) where your cpp files have a #include "logger.h"
, which is the code you show above. You now want to merge both codebases into a single codebase.
Then, by construction, every .cpp file only ever #include
s one or the other logger.h
. Furthermore, every .cpp file will have its own copy of log_inst
because you declared it as a static
variable in the header.
I suggest extracting everything but the static
variable into a logger-common.h
.
You can then have a logger-backup.h
with the following contents:
#include "logger-common.h"
static logger< file_log_policy > log_inst(GetAppDataPath()+ "\\Logs\\backup.log");
and vice versa for logger-restore.h
.
This still means you need to touch up the #include
s for your codebases, but that is an order of magnitude less work than changing every LOG
call.
If you really don't want to do that either I suppose you can play with the order of include directories for the files in each codebase to make sure they see "their" logger.h first, but it will horribly confuse your IDE and coworkers.