C ++ Primer study note _ 24 _ class and data abstraction (10) -- static and Singleton modes, auto_ptr and Singleton modes, const member functions, const objects, mutable modifiers, constmutable

Source: Internet
Author: User

C ++ Primer study note _ 24 _ class and data abstraction (10) -- static and Singleton modes, auto_ptr and Singleton modes, const member functions, const objects, mutable modifiers, constmutable

C ++ Primer study note _ 24 _ class and data abstraction (10) -- static and Singleton modes, auto_ptr and Singleton modes, const member functions, const objects, mutable Modifiers

Preface

[Example] What are the five basic principles of object-oriented writing?

Answer: single responsibility principle, open and closed principle, dependency inversion principle, interface isolation principle, and Lee's replacement principle

Rys replacement principle: child types must be able to replace their base types.

There are three types of design patterns: creation, structure, and behavior.


I. static and Singleton Modes

1. Singleton Mode
The intention of Singleton mode: ensure that a class has only one instance and provide a global access point to it.
(1) first form
# Include <iostream> # include <string> using namespace std; class Singleton {private: static Singleton s; int I; Singleton (int x): I (x) {cout <"Singleton" <endl;} Singleton & operator = (Singleton &); // The value of Singleton (const Singleton &) is not allowed; // public copying is not allowed: static Singleton & instance () {return s;} int getValue () {return I;} void setValue (int x) {I = x ;}}; Singleton :: s (47); // defines the static member sint main () {Singleton & s = Singleton: instance (); cout <s. getValue () <endl; Singleton & s2 = Singleton: instance (); s2.setValue (9); cout <s. getValue () <endl; return 0 ;}
Running result:
Singleton
47
9
The preceding Implementation implements the single-column mode by returning a reference. If a pointer instead of a reference is returned, the user may accidentally delete the pointer. Therefore, the above implementation is safer than returning the pointer.

(2) second form
# Include <iostream> # include <string> using namespace std; class Singleton {private: int I; Singleton (int x): I (x) {cout <"Singleton" <endl;} void operator = (Singleton &); Singleton (const Singleton &); // copying public: static Singleton & instance () is not allowed () {static Singleton s (47); return s;} int getValue () {return I;} void setValue (int x) {I = x ;}}; int main () {Singleton & s = Singleton: instance (); cout <s. getValue () <endl; Singleton & s2 = Singleton: instance (); s2.setValue (9); cout <s. getValue () <endl; return 0 ;}
Running result:
Singleton
47
9
In the preceding method, the singleton mode is implemented by creating static objects in the member functions.
Note that the preceding two methods do not take thread security into account. If the application needs to be applied in a multi-threaded environment, a lock is required.

[Example: Prohibit copying and assign values. The default constructor creates an object]
# Include <iostream> using namespace std; class Singleton {public: static Singleton * GetInstance () {if (instance _ = NULL) {instance _ = new Singleton ;} return instance _;}~ Singleton () {cout <"~ Singleton... "<endl;} private: Singleton (const Singleton & other); // place the copy function in private. Do not copy Singleton & operator = (const Singleton & other ); // do not assign values to Singleton () // do not create an object {cout <"Singleton... "<endl;} static Singleton * instance _;}; Singleton * Singleton: instance _; int main (void) {// Singleton s1; // Error, call the default constructor Singleton * s1 = Singleton: GetInstance (); Singleton * s2 = Singleton: GetInstance (); // Singleton s3 (* s1); // Error, call the copy constructor return 0 ;}
Running result: Singleton...


Although the above program calls two GetInstance functions, it only calls the constructor once to create an object. Declare the value assignment operator and copy constructor as private and prohibit copying. However, the program has a problem that the object will not be destructed at the time of survival.


2. To solve the problem that the object will not be destructed, you can use a static nested class object to solve the problem:

# Include <iostream> using namespace std; class Singleton {public: static Singleton * GetInstance () {if (instance _ = NULL) {instance _ = new Singleton ;} return instance _;}~ Singleton () {cout <"~ Singleton... "<endl;} class Garbo {public :~ Garbo () {if (Singleton: instance _! = NULL) {delete instance _ ;}}; private: Singleton (const Singleton & other); // place the copy function in private, do not copy Singleton & operator = (const Singleton & other); // do not assign a value to Singleton () // do not create an object {cout <"Singleton... "<endl;} static Singleton * instance _; static Garbo garbo _; // use the deterministic structure of the object}; Singleton: Garbo Singleton: garbo _; singleton * Singleton: instance _; int main (void) {// Singleton s1; // Error, call the default constructor Singleton * s1 = Singleton: GetInstance (); singleton * s2 = Singleton: GetInstance (); // Singleton s3 (* s1); // Error, call the copy constructor return 0 ;}
Running result: Singleton...
~ Singleton...

Explanation: using the deterministic destructor of static nested objects, The Garbo class destructor are called to delete the pointer of the singleton class in the destructor.


3. The above method is cumbersome. You can also return a reference to a local static object to solve the problem:

# Include <iostream> using namespace std; class Singleton {public: static Singleton & GetInstance () {static Singleton instance; // return instance of a local static object ;}~ Singleton () {cout <"~ Singleton... "<endl;} private: Singleton (const Singleton & other); // place the copy function in private. Do not copy Singleton & operator = (const Singleton & other ); // do not assign values to Singleton () // do not create an object {cout <"Singleton... "<endl ;}; int main (void) {Singleton & s1 = Singleton: GetInstance (); Singleton & s2 = Singleton: GetInstance (); return 0 ;}
Running result: Singleton...
~ Singleton...

Explanation: Partial static objects are initialized only once. Therefore, the same object is obtained by calling the GetInstance function multiple times. Because the function uses static objects, it is not thread-safe.


4. You can also use the auto_ptr smart pointer to solve the problem. The program is as follows. We will discuss auto_ptr in detail later.

#include <iostream>#include<memory>using namespace std;class Singleton{public:    static Singleton *GetInstance()    {        if (instance_.get() == NULL)        {            instance_ = auto_ptr<Singleton>(new Singleton);        }        return instance_.get();    }    ~Singleton()    {        cout << "~Singleton ..." << endl;    }private:    Singleton(const Singleton &other);    Singleton &operator=(const Singleton &other);    Singleton()    {        cout << "Singleton ..." << endl;    }    static auto_ptr<Singleton> instance_;};auto_ptr<Singleton> Singleton::instance_;int main(void){    Singleton *s1 = Singleton::GetInstance();    Singleton *s2 = Singleton::GetInstance();    return 0;}
Running result:
Singleton...
~ Singleton...

5. Hungry Chinese Singleton mode (Initialization is completed during class loading, so the class loading is slow, but the object retrieval speed is fast)

In fact, all the preceding examples of Singleton mode are NOT thread-safe. Suppose that if the two threads run to the statement if (instance = null) at the same time, the instance is not created yet, both threads will create an instance. If you do not want to lock the thread to implement thread security, you can use the hunger mode (that is, an instance can be created before the main function ):

# Include <iostream> using namespace std; class Singleton {public: static const Singleton * GetInstance () {return instance _;}~ Singleton () {cout <"~ Singleton... "<endl;} class Garbo {public :~ Garbo () {if (Singleton: instance _! = NULL) {delete instance _ ;}}; private: Singleton (const Singleton & other); // place the copy function in private, do not copy Singleton & operator = (const Singleton & other); // do not assign a value to Singleton () // do not create an object {cout <"Singleton... "<endl;} static const Singleton * instance _; static Garbo garbo _; // use the deterministic structure of the object}; const Singleton * Singleton :: instance _ = new Singleton (); Singleton: Garbo Singleton: garbo _; int main (void) {// Singleton s1; // Error, call the default const Singleton * s1 = Singleton: GetInstance (); const Singleton * s2 = Singleton: GetInstance (); // Singleton s3 (* s1 ); // Error, call the copy constructor return 0 ;}

Running result:
Singleton...
~ Singleton...


6. You can also use the locking method. The details will be discussed later.


2. const member functions, const objects, and mutable Modifiers

1. const member functions

The const member function does not modify the object state.

The const member function can only access the value of a data member, but cannot modify it.


2. const object

If an object is specified as const, the compiler is told not to modify it.
Definition of a const object:

Const class name Object Name (parameter table );

The const object cannot call non-const member functions.


3. mutable Modification

Data members modified with mutable can be modified even in the const object or in the const member function.

# Include <iostream> using namespace std; class Test {public: Test (int x): x _ (x), outputTimes _ (0) {} int GetX () const {cout <"const GetX... "<endl; // x _ = 100; // Error, try to modify the data member return x _;} int GetX () {cout <" GetX... "<endl; return x _;} void Output () const {cout <" x = "<x _ <endl; outputTimes _ ++ ;} int GetOutputTimes () const {return outputTimes _;} private: int x _; mutable int outputTimes _; // mutable modifier}; int main (void) {const Test t (10); t. getX (); Test t2 (20); t2.GetX (); t. output (); t. output (); cout <t. getOutputTimes () <endl; return 0 ;}
Running result:

Const GetX...
GetX...
X = 10
X = 10
2



Refer:

C ++ primer version 4
Valid tive C ++ 3rd

Http://blog.csdn.net/jnu_simba/article/details/9282235

Http://blog.csdn.net/zjf280441589/article/details/24704603

C ++ programming specifications

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.