I. Static and Singleton Modes
The Singleton mode is a simple design mode, which requires:
Ensure that a class has only one instance and provides a Global Access Point
Copy prohibited
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
# 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 ); Singleton & operator = (const Singleton & other ); Singleton () { Cout <"Singleton..." <Endl; } Static Singleton * instance _; }; Singleton * singleton: instance _; Int main (void) { // Singleton S1; // Singleton S2;
Singleton * S1 = singleton: getinstance (); Singleton * S2 = singleton: getinstance (); // Singleton S3 (* S1); // call the copy constructor
Return 0; } |
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.
To solve the problem that objects are not destructed, you can use a static nested class object to solve the problem:
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
|
# Include <iostream> Using namespace STD;Class Singleton { Public: Static Singleton * getinstance () { If (instacne _ = NULL) { Instacne _ = new Singleton; } Return instacne _; } ~ Singleton () { Cout <"~ Singleton... "<Endl; } // Static void free () //{ // If (instacne _! = NULL) //{ // Delete instacne _; //} //}
Class Garbo { Public: ~ Garbo () { If (singleton: instacne _! = NULL) { Delete instacne _; } } }; PRIVATE: Singleton (const Singleton & other ); Singleton & operator = (const Singleton & other ); Singleton () { Cout <"Singleton..." <Endl; } Static Singleton * instacne _; Static Garbo _; // use the deterministic structure of the object }; Singleton: Garbo singleton: Garbo _; Singleton * singleton: instacne _; Int main (void) { // Singleton S1; // Singleton S2;
Singleton * S1 = singleton: getinstance (); Singleton * S2 = singleton: getinstance (); // Singleton S3 (* S1); // call the copy constructor
Return 0; } |
The deterministic structure of a static nested object calls the Garbo class destructor and deletes the pointer of the singleton class in the destructor.
The above method is cumbersome. You can also return the reference of a local static object to solve the problem:
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
# Include <iostream> Using namespace STD;Class Singleton { Public: Static Singleton & getinstance () { Static Singleton instance; // local static object Return instance; } ~ Singleton () { Cout <"~ Singleton... "<Endl; } PRIVATE: Singleton (const Singleton & other ); Singleton & operator = (const Singleton & other ); Singleton () { Cout <"Singleton..." <Endl; } }; Int main (void) { Singleton & S1 = singleton: getinstance (); Singleton & S2 = singleton: getinstance (); Return 0; } |
The local static object is initialized only once, so the same object is obtained by calling the getinstance function multiple times. Because the function uses static objects, it is not thread-safe. In fact, you can also use the auto_ptr smart pointer to solve the problem. The program is as follows. For more information about auto_ptr, see here.
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
# 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 S2;
Singleton * S1 = singleton: getinstance (); Singleton * S2 = singleton: getinstance (); // Singleton S3 (* S1); // call the copy constructor
Return 0; } |
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.
Data members modified with mutable can be modified even in the const object or in the const member function.
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
# Include <iostream> Using namespace STD;Class Test { Public: Test (int x): X _ (x), outputtimes _ (0) { } Int getx () const { Cout <"const getx..." <Endl; // X _ = 100; 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 _; }; Int main (void) { Const test T (10 ); T. getx (); Test T2 (20 ); T2.getx (); T. Output (); T. Output (); Cout <t. getoutputtimes () <Endl; Return 0; } |
Iii. Const usage Summary
You can make a summary of the usage of const:
Refer:
C ++ primer version 4
Valid tive C ++ 3rd
C ++ programming specifications