Initializing static pointer reset after initialization
I have two classes:
class BasicLogger {
//...
}
class Logger {
public:
static boost::shared_ptr<Logger> log_;
static BasicLogger &log(const std::string &key){
if (!log_) {
log_.reset(new Logger());
}
return (*log_)(key);//calls operator()
}
virtual BasicLogger & operator()(const std::string &key);
virtual ~Logger();
};
//definition of static member
boost::shared_ptr<Logger> Logger::log_;
Then somewhere in the code I use the above classes:
namespace{
BasicLogger & csv = Logger::log("trip.csv");
}
My problem started when I noticed that it was ~Logger()
never called, so I started debugging. First, the control moved to a string BasicLogger & csv = Logger::log("trip.csv");
which eventually initialized my variablestatic shared pointer
Logger::log_
THEN a line is executed boost::shared_ptr<Logger> Logger::log_;
which will reset log_
back to null
!. I expect the shared pointer to Logger::log_
come out of acope at the end of my application and do some logic by calling ~Logger()
, but it never gets called.
Am I following wrong / bad practice? Any suggestions?
thank
source to share
You are looking at Fiasco's Static Initialization Order (also good info on https://isocpp.org/wiki/faq/ctors )
The most convenient way to "fix" is
- use local static function instead of globals
- Use local file locators (within one translation unit, initialization order is defined)
So:
static boost::shared_ptr<Logger>& getLog() {
static boost::shared_ptr<Logger> log_;
if (!log_) {
log_.reset(new Logger());
}
return log_;
};
static BasicLogger &log(const std::string &key){
return (*getLog())(key);//calls operator()
}
Watch Live On Coliru
However, it looks like you really want to save weak_ptr
there.
source to share