C ++ design mode: Singleton pattern)

Source: Internet
Author: User

Definition: the single-piece mode ensures that a class has only one instance and provides a global access point.

Implementation 1:

#include <iostream>
using namespace std;

class CSingleton
{
public:
static CSingleton* getInstance();
static void cleanInstance();
int getValue();
void setValue(int iValue);
private:
int m_iValue;
static CSingleton* m_pSingleton;
CSingleton();
~CSingleton();
};

CSingleton* CSingleton::m_pSingleton = NULL;

CSingleton::CSingleton()
{
cout << "Constructor" << endl;
}

CSingleton::~CSingleton()
{
cout << "Destructor" << endl;
}

CSingleton* CSingleton::getInstance()
{
if (NULL == m_pSingleton)
{
m_pSingleton = new CSingleton();
}
return m_pSingleton;
}

void CSingleton::cleanInstance()
{
delete m_pSingleton;
}

int CSingleton::getValue()
{
return m_iValue;
}

void CSingleton::setValue(int iValue)
{
m_iValue = iValue;
}

int main()
{
CSingleton* pSingleton1 = CSingleton::getInstance();
CSingleton* pSingleton2 = CSingleton::getInstance();
pSingleton1->setValue(123);
if (pSingleton1->getValue() == pSingleton2->getValue())
{
cout << "Two objects is the same instance" << endl;
}
else
{
cout << "Two objects isn't the same instance" << endl;
}

CSingleton::cleanInstance();
return 0;
}

I believe that most of my colleagues like to use the single-piece mode above. If it is a single thread, it is okay, but if it is a multi-thread, then it is very likely that two different objects will be returned.

Csingleton: When getinstance is used, if both threads run the if Statement at the same time, but the constructor has not been called yet, imagine the consequences. What should we do? See the implementation below.
Implementation 2:
# Include <iostream>
Using namespace STD;

Class csingleton
{
Public:
Static csingleton * getinstance ();
Static void cleaninstance ();
Int getvalue ();
Void setvalue (INT ivalue );
PRIVATE:
Int m_ivalue;
Static csingleton * m_psingleton;
Csingleton ();
~ Csingleton ();
};

// This single piece is instantiated when the process starts to run, also known as "eager" to create an instance
Csingleton * csingleton: m_psingleton = new csingleton ();

Csingleton: csingleton ()
{
Cout <"constructor" <Endl;
}

Csingleton ::~ Csingleton ()
{
Cout <"destructor" <Endl;
}

Csingleton * csingleton: getinstance ()
{
Return m_psingleton;
}

Void csingleton: cleaninstance ()
{
Delete m_psingleton;
}

Int csingleton: getvalue ()
{
Return m_ivalue;
}

Void csingleton: setvalue (INT ivalue)
{
M_ivalue = ivalue;
}

Int main ()
{
Csingleton * psingleton1 = csingleton: getinstance ();
Csingleton * psingleton2 = csingleton: getinstance ();
Psingleton1-& gt; setvalue (123 );
If (psingleton1-> getvalue () = psingleton2-> getvalue ())
{
Cout <"two objects is the same instance" <Endl;
}
Else
{
Cout <"two objects isn' t the same instance" <Endl;
}

Csingleton: cleaninstance ();
Return 0;
}
Haha, are you clear? The single piece is instantiated when the process is running, but it does not seem to be able to achieve the purpose of delayed instantiation. It would be a waste of resources if our objects occupy a large amount of resources and we do not use this single item during the whole process. There is a better way.
Implementation 3:
#include <iostream>
using namespace std;

class CSingleton
{
public:
static CSingleton* getInstance();
int getValue();
void setValue(int iValue);
private:
int m_iValue;
CSingleton();
~CSingleton();
};

CSingleton::CSingleton()
{
cout << "Constructor" << endl;
}

CSingleton::~CSingleton()
{
cout << "Destructor" << endl;
}

CSingleton* CSingleton::getInstance()
{
static CSingleton single;
return &single;
}

int CSingleton::getValue()
{
return m_iValue;
}

void CSingleton::setValue(int iValue)
{
m_iValue = iValue;
}

int main()
{
cout << "Process begin" << endl;
CSingleton* pSingleton1 = CSingleton::getInstance();
CSingleton* pSingleton2 = CSingleton::getInstance();
pSingleton1->setValue(123);
if (pSingleton1->getValue() == pSingleton2->getValue())
{
cout << "Two objects is the same instance" << endl;
}
else
{
cout << "Two objects isn't the same instance" << endl;
}
return 0;
}
Check the running result:

Process begin
Constructor
Two objects is the same instance
Destructor

Is it the same as expected? Declaring a single piece as a static member in the member function can achieve both the delay instantiation and thread security purpose, and check whether the program exits at the end of the result, what about automatically calling the Destructor? In this way, we can release the resources in the destructor. When the program exits, the process will automatically release these static members.

 
Reference books: head first design model

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.