-1

When I try to initialize a static member in my Action.cpp file via

ILogger & Action::m_activeLogger = DefaultLogger();

the compiler (C++11 + Linux) says:

cannot bind non-const lvalue reference of type "ILogger &" to an rvalue of type ILogger

How can I initialize my static member variable pointing to the instance?

Minimal example:

I have an interface base class (pure virtual)

base.h:

class ILogger {
public:
    virtual ~ILogger();
    virtual void write(std::string msg);
}

with DefaultLogger.h as an derived class as implementation (CPP file not shown here):

class DefaultLogger : public ILogger {
public:
    ~DefaultLogger();
    void write(std::string msg);
}

In Action.h I am using a static member variable with a reference to the base class:

class Action {
    static ILogger & m_activeLogger;
    // getter/setter to register another logger...
}

How can I initialize the static member variable m_activeLogger with my derived class?

R Yoda
  • 8,358
  • 2
  • 50
  • 87

1 Answers1

1

Store your logger not by reference, but with a unique_ptr and dereference it for the accessor:

class Action {
    static std::unique_ptr<ILogger> m_activeLogger;
    // getter/setter to register another logger...
}

And then should have an accessor to get it:

ILogger& get_instance(){return * m_activeLogger;}

Otherwise, you won't be able to set another logger! At least not with a reference.

Side note, the virtual call should probably take a const& to the string, and then tag them with override:

void write(const std::string& msg) override;
Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
  • Thanks for your very valuable response, it took me some time to read the background docs! `unique_ptr` seems to work. I am only having problems to understand the idea behind the `get_instance method. Why returning a pointer to an `unique_ptr` and interpreting it as `ILogger`? Shall it replace the getter **and** setter? I would add this setter: `void setLogger(std:unqie_ptr newlogger)` (which requires `move()` to pass the argument)... – R Yoda Nov 19 '18 at 06:43
  • Yes, setLogger would get a unique_ptr via more. Then I'm not returning a pointer to a unique_ptr for the get instance, I'm returning a ref to the logger. – Matthieu Brucher Nov 19 '18 at 07:46
  • For other readers to understand the idea behind `get_instance`: `*` is overloaded and returns the raw pointer (like `get()`). It is OK not to return an `unique_ptr` since the ownership is not moved and an `unique_ptr` does only guarantee to "free" (delete) the underlying object but **not** meant to solve dangling pointers. – R Yoda Nov 19 '18 at 22:00