简体   繁体   中英

Build a library in C++ which does not require class instantiation

Sorry if this seems to be a beginner question, but I can't seem to work out the best approach for my C++ library. I have build a static library, which contains driver API handling code. Currently in order to use it in a higher layer of the software (a simple app with GUI), I need to link the library to the project and create a new instance of a class which exists in this library to access all of its public methods. When a new instance of this class is created, all necessary objects required by the code to work are initialized. I would like to skip the instantiation step and enable the potential users to have it working only by including the library in their code. To picture this better, here's a code example:

What I currently have:

#include "myLibrary.h"

// Some GUI code here

MyLibrary *mLib;
mLib = new MyLibrary;

// Using the library methods
mLib->startProcess();

What I would like to have:

#include "myLibrary.h"

MyLibrary::startProcess();

I am working in Qt Creator, but don't mind migrating to a different IDE (Visual Studio would also be fine). The files I have in this projects are:

  • MyLibrary.h (declarations)
  • MyLibrary_global.h (an include list and export settings created by Qt Creator)
  • MyLibrary.cpp (implementation)

Any help would be appreciated. In case further clarification on my issue is needed, I will edit this question to make it clear.

EDIT: After digging in the driver API documentation, I have found out, that the way it is implemented will require me to create an instance of the MyLibrary class. I have gotten plenty knowledge from the comments below and marked the singleton-response as valid, since that would be the way for me to proceed if it was possible.

Supposed you have this:

 #include "myLibrary.h" // Some GUI code here MyLibrary *mLib; mLib = new MyLibrary; // Using the library methods mLib->startProcess();

Your library can hide the MyLibrary object like this:

startProcess() {
    static MyLibrary* myLib = new MyLibrary;
    myLib->startProcess();
}

Such that the user code looks like this:

 #include "myLibrary.h" MyLibrary::startProcess();

The function local static myLib will be initialized on first call of the method.

However, you probably want to use the MyLib instance also from other places in your code and wrapping it inside startProcess is not really an option. You'd rather use the much frowned upon Singleton Pattern. Here is a Q&A abuot the Meyers Singleton: Is Meyers' implementation of the Singleton pattern thread safe? .

I am not going into details, because the Singleton Pattern is well documented across the web. Only to outline the rough idea, this would allow you to get the desired user code (not tested):

struct MyLibrary {
     static void startProcess() {
         instance().doStartProcess();
     }
     private:

     MyLibrary() = default;          // private constructor
     MyLibrary(MyLibrary&) = delete; // no copies
     static MyLibrary& instance() {
          static MyLibrary myLib;              // the actual instance
          return myLib;
     }
     void doStartProcess(){
          // actual implementation
     }
}

Note that the actual instance myLib is lazily initialized, ie only the first time instance() is called the function local static myLib is initialized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM