Singleton implementation in C
Keywords: ANSI C , Singleton, Static Member, Initialize, Auto_PTR, STD, STL, IMPLEMENT, Implementation
Singleton in ANSI C is difficult to say, it is easy to say that it is easy, many people write ANSI C Singleton Class has errors. This article discusses how to write Singleton Class in ANSI C , I hope to help everyone.
"Design Mode" is written to return the pointer:
Class singleton {public: static singleleton * instance (); protected: singleton (); private: static singleleton * _INSTANCE;
The corresponding implementation CPP file is:
Singleton * singleton ::};};};
The purpose of designing the constructor as protected is to prevent NEW outside of the Class, some people may be designed to be private, if you consider that you may inherit this class, you still need to add a Virtual destructor function. In order to prevent others from copying the Singleton object: Singleton * psingleton = singleton :: instance (); singleton s1 = * psingleton; Singleton S2 = * psingleton; need to turn the copy constructor function into Private.
But what exists here is, when do you delete a Singleton object? According to a basic principle of C , where is the object to create where it is destroyed, and you should also put a Destroy method to delete the Singleton object. If you forget to delete it, it is more troublesome. The Instance function also has a multi-threaded lockup problem. If the instance function starts and the end and the end is locked and unlocked, the entire function performance will fall a lot. This is not a good design. There is a small change that avoids forgetting the problem of deleting the Singleton object to bring memory leaks. That is to use STD: Auto_PTR to include a Singleton object, define a Class Static Member Auto_PTR object, automatically delete the Singleton object when the descent static auto_ptr variable is time. In order not to let the user DELETE SINGETON object, you need to turn the designer function to protected by public. The following is the header file singletonautoptr.h:
#include
Using namespace std;
Class CsingletonAutoptr
{
Private:
Static auto_ptr
M_AUTO_PTR;
Static csingletonautoptr * m_instance;
protected:
CSITONAUTOPTR ();
CSITONAUTOPTR (Const Csingletonautoptr &);
Virtual ~ csingletonautoptr ();
// allow auto_ptr to delete, using protected ~ csingletonautoptr () Friend Class Auto_PTR
;
PUBLIC:
Static csingletonautoptr * getInstance ();
Void test ();
}
The corresponding Singletonautoptr.cpp is as follows:
#include "singletonautoptr.h" #include
// Initial Static Member Vars Here Csingletonautoptr * csingletonautoptr :: M_INSTANCE = NULL; Auto_PTR
CSITONAUTOPTR :: m_auto_ptr;
//// Construction / Destruction // CSingletonAutoPtr :: CSingletonAutoPtr () {cout << "CSingletonAutoPtr :: CSingletonAutoPtr ()" << endl; // put single object into auto_ptr object m_auto_ptr = auto_ptr
(this);
}
CSITONAUTOPTR :: ~ csingletonautoptr () {cout << "CSITONAUTOPTR :: ~ csingletonautoptr () << endl;}
CSITONAUTOPTR * CSIINGETONAUTOPTR :: getInstance () {// begin lock // ....
IF (m_instance == null) m_instance = new csingletonautoptr ();
// end lock // ...
Return M_INSTANCE;
Void csingletonautoptr :: test () {cout << "csingletonautoptr :: test ()" << endl;}
Call method:
CSITONAUTOPTR * psingleton = csingletonautoptr :: getInstance (); psingleton-> test ();
Writing Singleton in a C requires this to be so hard, it is very unexpected. There are many people who have never used Auto_Ptr, and std: auto_ptr it is not perfect, it is based on object ownership mechanism, in contrast, Apache log4cxx has auto_ptr, based on object count, more good. Just use a good auto_ptr to use log4cxx, not very good for many projects. Of course, STD: auto_ptr in ANSI C is enough to write the above example.
Another idea is that the GetInstance function is designed to Static Member, because in general, the Singleton object is not large, and the STATIC Member must always occupy memory, the problem is not big. The destructor here must be set to public. The following is the header file SINGESTITICOBJ.H
class CSingletonStaticObj {private: static CSingletonStaticObj m_instance; protected: CSingletonStaticObj (); CSingletonStaticObj (const CSingletonStaticObj &); public: virtual ~ CSingletonStaticObj (); // must public static CSingletonStaticObj & GetInstance (); void Test ();}; corresponding SingleStaticObj. The CPP file is:
#include "singletonstaticobj.h" #include
Using namespace std;
CSITONSTATICOBJ CSITONSTATICOBJ :: M_INSTANCE
CSITONSTATICOBJ :: CSINGletonStaticobj () {cout << "csingletonStaticobj :: csingletonStaticobj () << endl;}
CSITONSTATICOBJ :: ~ cSingletonStaticobj () {cout << "CSITONSTATICOBJ :: ~ csingletonStaticobj () << endl;}
CSITONSTATICOBJ & CSITONSTATICOBJ :: getInstance () {Return m_instance;
Void csingletonStaticobj :: test () {cout << "csingletonStaticobj :: test ()" << Endl;
Call method:
CsingletonStaticobj & Singleton = csingletonautoptr :: getInstance (); singleleton.test ();
From the code quantity, it seems to be easier to use Static Member REF. I am more embarrassed to use this method.
However, not all situations are suitable for STATIC MEMBER SINGETON. For example, GetInstance needs to dynamically decide whether to return different instances, it is not possible. For example, FileSystem :: GetInstance, run under Windows Must return new winfilesystem, Linux / UNIX runs under Windows Must return new LinuxFileSystem, this time you still need to use the above AUTO_PTR to include the Singleton pointer.
How to write Singleton to see everyone's project needs. The above code is compiled under Visual C 6.0 below.