Ogre irresponsible research (2) Application of the single-piece model, ogre: Singleton

Source: Internet
Author: User

This article mainly analyzes how the single-piece mode in the Ogre engine is used, that is, the analysis and use of the Ogre: Singleton class. Before getting started, I once again lamented that the highly handwritten things are different, not only taking care of different compilers, (GCC ), it also takes care of different versions of the VC compiler, one of which writes:

# If defined (_ msc_ver) & _ msc_ver <1200
Int offset = (INT) (T *) 1-(INT) (Singleton <t> *) (T *) 1;
Ms_singleton = (T *) (INT) This + offset );
# Else
Ms_singleton = static_cast <t *> (this );

What do Niang's, line 2 and line 3 mean? After analyzing for a long time, I guess it should be equivalent to the following sentence. It is for those early VC compilers that do not support the static_cast method and provide a static conversion method. Today we have learned something--and can actually perform static conversion like this. Remove some things that I don't understand but may be useful. The remaining "dry goods" are soy sauce.

# Pragma once

# Include "ogreprerequisites. H"

Namespace ogre {

/** Template class for creating single-instance global classes .*/

Template <typename T> class Singleton

{

Protected:

Static T * ms_singleton;

Public:

Singleton (void ){

Assert (! Ms_singleton );

Ms_singleton = static_cast <t *> (this );

}

~ Singleton (void)

{Assert (ms_singleton); ms_singleton = 0 ;}

Static T & getsingleton (void)

{Assert (ms_singleton); Return (* ms_singleton );}

Static T * getsingletonptr (void)

{Return ms_singleton ;}

};

}

 

Yes. Ogre declares a base class, singleton. It is also a template class. All entity classes that require the single-piece mode can inherit this base class and get the single-piece mode through inheritance. For example, the root class, known as "the source of everything", inherits the singleton class. This is a bit new for us, maybe it's too weak. I wrote a demo to serve as an analysis demo for the Ogre single-piece mode. The brief code is as follows:

// ----- Singleton. h ----------- base class -- template class -----------------

# Pragma once
# Include <iostream>
Using namespace STD;

// Single-piece mode demonstration of the template base class:

Namespace hawkwang {

Template <typename T>
Class Singleton
{
Protected:
Static T * ms_singleton;
Public:
Singleton (void ){
Assert (! Ms_singleton );
Ms_singleton = static_cast <t *> (this );
Cout <"Singleton constructor! "<Endl;
}
~ Singleton (void ){
Assert (ms_singleton );
Ms_singleton = 0;
}
Static T * getsingletonptr (void ){
Return ms_singleton;
}
Static T & getsingleton (void ){
Assert (ms_singleton );
Return (* ms_singleton );
}
};
}

Note that ms_singleton must be a static member variable. Likewise, the getsingleton and getsingletonptr methods are the same, static classes.

// --------- Bananatree. h --- banana tree header file, entity class ------

# Pragma once
# Include "Singleton. H"

Namespace hawkwang {
Class bananatree: Public Singleton <bananatree>
{
Public:
Bananatree ();
~ Bananatree ();
Void banana ();
Static bananatree * getsingletonptr (void );
Static bananatree & getsingleton (void );
};
}

// ----- Bananatree. cpp --- rubber class source file ----------------------

# Pragma once
# Include "stdafx. H"
# Include "bananatree. H"
# Include <iostream>
Using namespace STD;

Namespace hawkwang {
Template <> bananatree * Singleton <bananatree>: ms_singleton = 0;
Bananatree & bananatree: getsingleton (){
Assert (ms_singleton );
Return (* ms_singleton );
}

Bananatree * bananatree: getsingletonptr (){
Return ms_singleton;
}

Bananatree: bananatree () {cout <"constructor of bananatree" <Endl ;}
Bananatree ::~ Bananatree () {cout <"destructor of bananatree" <Endl ;}
Void bananatree: banana () {cout <"I Am a lovely banana" <Endl ;}
}

// ------------- Appletree. h ---- header file of the apple tree class, entity class ------

# Pragma once
# Include "Singleton. H"

Namespace hawkwang {
Class Appletree: Public Singleton <Appletree> {
Public:
Appletree ();
~ Appletree ();
Void Apple ();
Static Appletree & getsingleton (void );
Static Appletree * getsingletonptr (void );
};
}

// ------ Appletree. cpp ---- source code of the apple tree class --------

# Pragma once

# Include "stdafx. H"
# Include "Appletree. H"
# Include <iostream>
Using namespace STD;

Namespace hawkwang {
Template <> Appletree * Singleton <Appletree>: ms_singleton = 0;

Appletree * Appletree: getsingletonptr () {return ms_singleton ;}
Appletree & Appletree: getsingleton () {assert (ms_singleton); Return (* ms_singleton );}
Appletree: Appletree () {cout <"constructor of Appletree" <Endl ;}
Appletree ::~ Appletree () {cout <"destructor of Appletree" <Endl ;}
Void Appletree: Apple () {cout <"I Am a lovely apple" <Endl ;}
}

// -------- Main function ---------------------------------

# Include "stdafx. H"
# Include "bananatree. H"
# Include "Appletree. H"
# Include <iostream>

Using namespace hawkwang;

Int _ tmain (INT argc, _ tchar * argv [])
{
Bananatree bananaroot;
Appletree appleroot;

Bananatree: getsingleton (). Banana ();
Appletree: getsingleton (). Apple ();

Char C;
STD: CIN> C;

Return 0;
}

Oh, sure enough, the handwriting is different. Use a template class to make the singleton class the base class of other classes. All entity classes that require the singleton mode only need to inherit the singleton class and implement the getsingleton and getsingletonptr methods. Note: The method for initializing the base class ms_singleton static member variable is as follows:

Template <> Appletree * Singleton <Appletree>: ms_singleton = 0;

Note that static member functions must be declared in the Appletree class! Because it is a static pull ....... How is a single piece reflected? Look at the singleton class code:

Assert (! Ms_singleton );

If Singleton has been assigned a value, when the constructor is called again, this assertion is false. In this case, an error is reported. This seemingly crude method implements the single-piece mode through the template base class and the derived method. The price of flexibility is rough ......, However, it can effectively ensure that only one instance inherits the derived class of the singleton class.

The method for accessing a single piece is very simple: "Class Name: getsingleton" "Class Name: getsingletonptr". Note that the singleton class is only used to implement a single piece, not for polymorphism. Therefore, do not use the singleton class as an interface to operate its derived classes in a multi-state manner.

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.