1

What is the appropriate way to accept a pointer to a class that is subsequently used within a static library across all objects within that library?

The classic case is a logger, which I will use as an example here.

Singletons are often used when dealing with loggers. This is ok, if it is defined entirely within the static library. However, what is the appropriate way to deal with it when the logger is external the library? How can you pass an instance in, but be used by all classes within the library?

Then use DI you say? Well, in my case, I can't use DI because some of the objects are created outside of the library.

So, what is the right pattern?

Here is some code which illustrates the concept of what I am trying to accomplish:

#include <string>
#include <vector>
#include <memory>
#include <iostream>

//=====================================================
//              Logger Libraray
//=====================================================
class Logger {
public:
    void Write( std::string message ) {
        std::cout << message.c_str() << std::endl;
    };
};

//=====================================================
//              Internal Libraray
//=====================================================
class Base {
public:
    Base() {};

    void SetLogger( std::shared_ptr<Logger> logger ) {
        logger_ = logger;
    };

    void Log( std::string message ) {
        if( logger_ != nullptr )
            logger_->Write( message );
    };

private:
    static std::shared_ptr<Logger> logger_;
};

class DerivedA : public Base {
public:
    DerivedA() {
        Log("In derived A");
    }
};

class DerivedB : public Base {
public:
    DerivedB() {
        Log("In derived B");
    }
};


//=====================================================
//              Library External Interface
//=====================================================
class Item : public Base {
public:
    std::string Name;

    Item() {
        Log( "Item created externally" );
    };
};

class Library : public Base {
public:
    Library() {};
    std::vector<Item> ItemList;

    void AssignLog(  std::shared_ptr<Logger> logger ) { 
        SetLogger( logger );
    };

    void process( ) {
        DerivedA a;
        DerivedB b;
    }
};

//=====================================================
//               External Program
//=====================================================
int main() {
    Logger log;
    log.Write("test");

    Library lib;
    lib.AssignLog( std::make_shared<Logger>(log));

    lib.process();
    Item item;
    item.Name = "Sample";
    lib.ItemList.push_back(item);
}
user3072517
  • 513
  • 1
  • 7
  • 21
  • Not sure I understand your exact problem, but you could create a third library exclusive for logging and have both the other library and your application link to it. The logging library would internally handle resources used for logging and provide only free-standing log functions. – Christian Hackl Mar 08 '15 at 14:05
  • The logging is actually in a different library. That is the point. I am trying to pass the library in to another library (and replaceable at run-time/startup). Within that, it is global, however. – user3072517 Mar 09 '15 at 19:01

0 Answers0