A simple main function free main program framework class based on C + +

When teaching children to learn C + + language, in order to explain the encapsulation, inheritance and polymorphism of C + +, I wrote a simple main program framework class. The application only needs to derive subclasses from the main program framework class and implement its run(...) Method, and then define a subclass instance.

The abstract code of the AbstractApplication class is as follows:

// absapp.h
#ifndef __ABSAPP_H
#define __ABSAPP_H
/**
 * AbstractApplication The abstract framework class of the application.
 * The application main class should derive from this class, override its pure virtual function run, and then define a global object instance of the application main class.
 * The application class should be included with. Main CPP / h (for console applications) or WinMain CPP / h (for Windows GUI applications).
 * To get command line arguments, the application should also #include "main.h" or #include "winmain.h".
 */
class AbstractApplication
{
   public:
      AbstractApplication()   {  instance = this;  }
      virtual ~AbstractApplication()  {}

   public:
      static AbstractApplication *getInstance()  {  return instance;  }
      static int start(void *params);

   protected:
      virtual int run(void *params) = 0;

      static AbstractApplication *instance;
};

#endif /* __ABSAPP_H */

// absapp.cpp
#include "absapp.h"

AbstractApplication *AbstractApplication::instance;

int AbstractApplication::start(void *params)
{
   instance->run(params);

   return 0;
}

The implementation code of the main() function of the console program is as follows:

// main.h
#ifndef __MAIN_H
#define __MAIN_H

typedef struct __tagMainArgs
{
   int argc;
   char **argv;
} MainArgs;

#endif /* __MAIN_H */


// main.cpp
#include "absapp.h"
#include "main.h"

int main(int argc, char *argv[])
{
   MainArgs args;
   args.argc = argc;
   args.argv = argv;
   return AbstractApplication::start(&args);
}

The WinMain function implementation code of Windows GUI program is as follows:

// winmain.h
#ifndef __WINMAIN_H
#define __WINMAIN_H

#include <windows.h>

typedef struct __tagWinMainArgs
{
   HINSTANCE hInstance;
   HINSTANCE hPrevInstance;
   LPSTR lpCmdLine;
   int nCmdShow;
} WinMainArgs;

#endif /* __WINMAIN_H */


// winmain.cpp
#include "absapp.h"
#include "winmain.h"

int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
   WinMainArgs args;
   args.hInstance = hThisInstance;
   args.hPrevInstance = hPrevInstance;
   args.lpCmdLine = lpszArgument;
   args.nCmdShow = nCmdShow;
   return AbstractApplication::start(&args);
}

The above code can be packaged with the compiler and made into a statically linked library file for application.

The test code is as follows:

// testCaseApp.cpp

#include <iostream>
#include <absapp.h>

using namespace std;

class TestCaseApp : public AbstractApplication
{
public:
   TestCaseApp()  {}
   virtual ~TestCaseApp()  {}

   virtual int run(void *params) override
   {
      cout << "Hello, no-main Application Framework." << endl;
      return 0;
   }

private:

};

TestCaseApp testCaseApp;

When the program is running, the running environment will first create the global instance testcaseapp object of testcaseapp class. When creating this object instance, the constructor of AbstractApplication is called first, and the static member AbstractApplication::instance is initialized to this. Since the testcaseapp object is being created at this time, the this pointer represents the testcaseapp object, so AbstractApplication::instance also points to the testcaseapp object. When the main() function can run, the testcaseapp object has been created. Then the main function calls AbstractApplication::start(...), AbstractApplication::start(...) Instance - > run (params) was called. Since instance already points to testcaseapp, instance - > run(...) What is called is the run(...) of the testcaseapp object Member function.

As can be seen from the above test code, in the view of the application program, this program has no main function and only one global object. This example uses the encapsulation, inheritance, polymorphism and other features of C + +, and solves the problem that C + + has been criticized for failing to get rid of the global main function. In fact, it just hides the main. However, without global functions, there are more global variables, which is actually not much better. In fact, any language always needs a global entry point. Java, which is called OO well, also needs to define a static main function in the main class. Excessive pursuit of "no global data" is meaningless.

Keywords: C++ Design Pattern Polymorphism

Added by sysgenmedia on Fri, 18 Feb 2022 06:49:04 +0200