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

+3


source to share


1 answer


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.

+2


source







All Articles