Singleton design pattern
Key Points On Learning:
1)
Protected constructor
2) Protected copy constructor and
assignment operator
3) POD types
// Declaration
class Singleton
{
public:
static
Singleton* Instance();
protected:
Singleton();
// constructor
Singleton(const
Singleton&);
// copy constructor
Singleton&
operator= (const
Singleton&); // assignment operator
private:
static Singleton* pinstance;
};
// Definition
Singleton* Singleton::pinstance = 0;
// initialize pointer
Singleton* Singleton::Instance ()
{
if (pinstance == 0)
// is it the first call?
{
pinstance = new
Singleton; // create sole instance
}
return pinstance;
// address of sole instance
}
Singleton::Singleton()
{
//... perform necessary
instance initializations
}
建構子是 protected,
因此無法使用直接宣告或動態配置的方式來建立物件:
Singleton* obj1 = new Singleton();
Singleton obj2;
可以確保只存在一份實體的物件,以下的程式碼回傳的皆是同一個實體
Singleton *p1 =
Singleton::Instance();
Singleton *p2 = p1->Instance();
Singleton & ref = * Singleton::Instance();
Appendix 1. Use private copy constructor and assignment operator to avoid object copying
If you don't want users of your class
to be able to assign objects of its type (password string objects are a good
example), you can declare a private assignment operator and copy constructor.
Please note that the compiler-synthesized copy constructor and assignment
operator are public, therefore, you have to define them explicitly as private
members in this case. For example:
class
NoCopy {
private:
NoCopy&
operator = (const NoCopy& other) {/*..*/}
NoCopy(const
NoCopy& other) {/*..*/}
public:
//...
};
void f()
{
NoCopy nc;
//fine, default constructor called
NoCopy nc2(nc);
//compile time error; attempt to call a private copy constructor
nc2 = nc;
//also a compile time error; operator= is private
}
Appendix 2. What is difference between [Singleton* obj = new Singleton;] and [Singleton* obj = new Singleton();]
首先必須先了解何謂 POD type,在C++的標準中有定義,而以下有一段來自於MSDN Magazine的說明:
C++ Q&A Calling Virtual Functions, Persisting View State, POD Type -- MSDN Magazine, November 2004
Q
I've seen the term "POD type" occasionally in literature
and documentation about C++ and the Microsoft® .NET Framework. What is a POD
type?
[Asked by Shelby Nagwitz]
A You might think a POD type is a data type that arrives from outer space wrapped in a green protective covering, but POD stands for Plain Old Data and that's just what a POD type is. The exact definition is rather gnarly (see the C++ ISO standard), but the basic idea is that POD types contain primitive data compatible with C. For example, structs and ints are POD types, but a class with a user-defined constructor or virtual function is not. POD types have no virtual functions, base classes, user-defined constructors, copy constructors, assignment operator, or destructor.
To conceptualize POD types you can copy them by copying their bits. Also, POD types can be uninitialized. For example:
struct RECT r; // value undefined POINT *ppoints = new POINT[100]; // ditto CString s; // calls ctor ==> not POD PS: "ditto" means "The same as stated above or before"
Non-POD types usually require initialization, whether by calling a default (compiler-supplied) constructor or your own.
In the old days, POD was important mostly for people writing compilers or C++ programs compatible with C. Nowadays, POD comes up in the context of .NET. In managed C++, managed types (both __value and __gc) can contain embedded native POD types. Figure 3 shows code that illustrates this. The managed Circle class can contain a POINT but not a CPoint. If you try to compile pod.cpp, you'll get error C3633: "Cannot define 'm_center' as a member of managed 'Circle' because of the presence of default constructor 'CPoint::CPoint' on class 'CPoint'."
///////////////////////////////////////////////////////////////////// // You can embed native POD types in a managed (__gc or __value) type. // Compile with cl /clr. #using <mscorlib.dll> // simple struct is a POD type struct POINT { int x; int y; }; // native class w/ctor: not POD! class CPoint : public POINT { CPoint() { x=y=0; } }; // Managed __gc type __gc class Circle { public: POINT center; // ok: embedded POD type CPoint m_center; // Error: not POD! int radius; };
接著在C++STANDARD-ISOIEC14882-1998 [§5.3.4, ¶15]
所以「Singleton* obj = new Singleton;」與「Singleton* obj = new Singleton();」有差別嗎?
Ans : No
參考文獻
1. Implementing the
Singleton Design Pattern
http://www.inquiry.com/techtips/cpp_pro/10min/10min0200.asp
2. Use private copy
constructor and assignment operator to avoid object copying
http://www.devx.com/tips/Tip/12570
3. C++ Q&A Calling
Virtual Functions, Persisting View State, POD Type -- MSDN Magazine, November
2004
http://msdn.microsoft.com/msdnmag/issues/04/11/CQA/default.aspx
4. POD Plain Ol'
Data
http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html
5.
C++STANDARD-ISOIEC14882-1998
http://www.ishiboo.com/~nirva/c++/C++STANDARD-ISOIEC14882-1998.pdf
6. ditto -
definition of ditto by the Free Online Dictionary, Thesaurus and Encyclopedia.
http://www.thefreedictionary.com/ditto
Written By James Liang @ 2007/01/29