Introduction to the singleton pattern and implementation of the C + + version

Source: Internet
Author: User
Tags system log

The main content of this post refers to the C + + singleton model, in this case, for the original author's patient and meticulous analysis of the explanation, expressed thanks. This article will be combined with this article, give their own understanding of the experiment and Code, as a summary of today's study.

Singleton mode, which is intended to ensure that a class has only one instance and provides a global access point externally, which is shared by all modules. This mode is widely used, such as System log output, operating system window manager, PC connected keyboard and so on.

Singleton mode is a design pattern, it's specific implementation and various language features, here is mainly introduced in C + + implementation, test platform for Win7 64-bit, VS2010 development environment.

According to the example of Reference blog post, this first lists the various implementation strategies, the following are Csingleton as the class name for example.

1. The use of a global object, such as called Csingleton G_instance, the advantage is convenient access, the disadvantage is not guaranteed that such objects unique, in addition to the global object, but also to create a local instance of the Csingleton.

2. Use the static member variable of the class, which is a private static member pointer, such as static CSingleton1 *m_pinstance; At this point, consider letting the class itself release the content that this member pointer points to when it is appropriate.

3. Use the static member variable of the class, this variable is a private static member, such as Static CSingleton1 m_pinstance;

Before giving the code, explain several points of knowledge:

1. Static members of a class, including member variables and member functions, belong to the class itself and all instance objects share the same copy.

2. Static member initialization operations have allocated space and completed initialization before entering the main function. Static member variables must be initialized outside the class body, and the initialization value is defined in a manner similar to csingleton1* csingleton::m_pinstance = null. If it is not initialized, then this member will not be allocated space and will not exist in the class.

4. Static members after the program exits the main function, it will go to the CRT class function cleanup, complete the program static variables, class destructors, such as the release of the call, the details do not need to consider, only need to know to exit the main function also needs to do cleanup work on the line.

3. A class declared inside a class becomes a nested class, which is generally used to declare classes that are used only within the class. If you must use it externally, you need to add a domain resolver:

OK, basic bedding complete, start code, start from the simple.

Static class variables, at first can be member variables of the class, but need to be initialized externally, not graceful. In fact, declaring a static local class variable in a static member function of a class is a more concise approach.

class  Csingleton {private : CSingleton      () //constructor is private  {} Csingleton (const  Csingleton &);  Csingleton & operator  = (const  Csingleton &); public : static  Csingleton & getinstance () {
   
    static  Csingleton instance;        
    //local static variable       
    return  instance; }  }; 
   

Static class pointer mode: This way to achieve, because there is allocated space, so there are more things to consider. Refer to the code in the article on the singleton mode of C + +, which shows the code without memory leaks after hands-on practice. Important places, all written in the comments, easy to understand.

Singlethon.cpp: Defines the entry point of the console application.
#include <iostream>
#include <Windows.h>
using namespace std;
Used to turn on CRT memory leak detection
#define
Multi-threaded Protection lock class
class Lock
{
Private:
    critical_section  //package Critical Zone
    Lock () {};
    Lock (const lock&) {};                                            
    operator= (const lock&) {};
Public:
    Lock (critical_section CS): M_cs (CS)
    {
        InitializeCriticalSection (&m_cs);
    }
    void Startlock ()
    {
        EnterCriticalSection (&m_cs);        
    }
    void Stoplock ()
    {
        Leave the critical section
        LeaveCriticalSection (&m_cs);
    }
    ~lock ()
    {
        It looks better to leave the critical section here.
        LeaveCriticalSection (&m_cs);
        When the critical section is not in use, destroy and release the resource
        DeleteCriticalSection (&m_cs);
    }
};
Self-modeled reference, implementation of a single-case mode
class Singlethon
{
    Inline class, can only be used in Singlethon, cannot be used directly externally
    class Cgarbo    //Unique function, in the destructor, delete the instance of Singlethon
    {
    Public:
        Cgarbo ()
        {
            "Constructor Cgarbo"<<endl;
        }
        ~cgarbo ()
        {
            if (singlethon::m_pinstance)
            {
                "Execute Cgarbo destructor function"<<endl;
                Delete singlethon::m_pinstance;
            }
        }
    };
Private:
    "Constructor Singlethon"<<endl;};    //Prohibit direct declaration Singlethon single;
    Singlethon (const singlethon&) {};                        //Prohibit indirect declaration Singlethon single2 (* (Singlethon::getinstance ()));
                                                                  or   Singlethon single2 = (* (Singlethon::getinstance ()));
    operator= (const singlethon&) {};        //Prohibit assignment operation     Singlethon single;single = * (Singlethon::getinstance ());
        
    Static singlethon* m_pinstance;
    Static Cgarbo Garbo;        //static member variable, the system automatically calls its destructor at the end of the program
    Static Critical_section CS;
Public:
    Static singlethon* getinstance ();
    ~singlethon ()
    {
        "Execute Singlethon destructor function"<<endl;
        It is not possible to release itself here, because the destructor of Cgarbox is executed prior to its destruction, and when it executes, it invokes the delete singlethon::m_pinstance;
        This triggers the destructor of the Singlethon itself, and here again the delete Singlethon::m_pinstance is called, which creates an infinite loop
        Errors in the stack overflow will eventually be error
        
    #if 0
        if (singlethon::m_pinstance)            
            Delete singlethon::m_pinstance;
        Singlethon::m_pinstance = NULL;
    #endif
    }
};
The following three words, indispensable
Singlethon::cgarbo Singlethon::garbo;
singlethon* singlethon::m_pinstance = NULL;
singlethon* singlethon::getinstance ()
{
    if (NULL = = m_pinstance)
    {
        Lock (CS);
        lock. Startlock ();
        if (NULL = = m_pinstance)
        {
            New Singlethon;
        }
        lock. Stoplock ();
    }    //Normal exit or exception throw, this will automatically call the lock's destructor, because the scope of lock is local
    return m_pinstance;
}
int Main ()
{
    Turn on the CRT memory leak detection function
    
    singlethon* P1 = Singlethon::getinstance ();
    singlethon* P2 = singlethon::getinstance ();
    if (P1 = = p2)
    {
        "single-mode test success!!" <<endl;
    }
    Else
    {
        "Singleton mode test failed !!" <<endl;
    }
    return 0;
}

The above code has several places to parse in detail:

1. When releasing a class, if there is a dynamic variable member in the class, it is generally necessary to release the contents of it first and then release the space of the class itself in the call destructor. Similarly, for example, in the vector<int*> array, if the direct array.clear, where the allocated memory space will be disclosed, the correct way is to first release the allocated content, and then empty space.

 for (vector<void *>::iterator it = V.begin (); It! = V.end (); it + +)     if (NULL! = *it)     {        delete *it;         *it = NULL;    } V.clear ();

2. The above code defines a lock class, encapsulating the related operations of the critical section, as a resource management class, the internal critical section variable, as a guarantee of multithreading security. Local resource management class variables allow the destructor to be called when an exception occurs, releasing critical zone resources

3. In the judgment, two times to improve efficiency. Because the method invocation generates an instance for the first time, and pinstance = = NULL is false in most cases, if you only judge once, you need to lock the instance before each fetch, and the efficiency is too low.

4. Define a nested class, and a corresponding static local variable, so that when the entire singleton is released, it can be used to find a singleton pointer, and then delete it, so there is no memory leak sent.

5. Use the memory leak detection function of CRT class function to check debugging easily.

At the end of the article, we give the test result diagram:

Ok!

Readers can add endpoints to each construct and destructor, or try commenting out Cgarbo's destructor debugs to see if there is a memory leak.

Long time no update article, this period of work is busy, busy not scary, terrible is no purpose, no motive of the busy.

Copyright NOTICE: This article for Bo Master original article, welcome reprint, reproduced Please indicate the source, thank you.

Introduction to the singleton pattern and implementation of the C + + version

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.