C + + Primer Learning Notes _24_ class and Data Abstraction (--static) with singleton mode, auto_ptr and singleton mode, const member function, const object, mutable modifier

Source: Internet
Author: User

C + + Primer Learning Notes _24_ class and Data Abstraction (--static) with singleton mode, auto_ptr and singleton mode, const member function, const object, mutable modifier

Objective

"Example" writes out the five basic principles of object-oriented?

Solution: Single Duty principle, open closure principle, dependency inversion principle, interface isolation principle and Richter replacement principle

Richter substitution principle: subtypes must be able to replace their base types.

There are three types of design patterns: Creation, structural, and behavioral patterns


First, static and single-case mode

1. Single Case mode
The intent of the singleton pattern:ensure that a class has only one instance and provides a global access point to access it。
(1) The first form of
#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&); Assignment    Singleton (const singleton&) is not allowed, copy public is not allowed:    static singleton& instance () {return s;}    int GetValue () {return i;}    void SetValue (int x) {i = x;}}; Singleton Singleton::s (47); Defines a 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;}
Operation Result:
Singleton
47
9
The above implementation implements a single-column pattern by returning a reference. If a pointer is returned instead of a reference, the user may accidentally delete the pointer, so the above implementation is more secure than the return pointer.

(2) The second form of
#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&); Copy public is not allowed:    static singleton& instance ()    {        static Singleton s ();        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;}
Operation Result:
Singleton
47
9
The above method implements a singleton pattern by creating a static object inside the member function.
Note that the above two methods do not consider the problem of thread safety, such as to be applied in multi-threaded environment, need to lock.

"Example: Prohibit copy, assign, default constructor create object action"
#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 copy function in private, prohibit copy    Singleton &operator= (const Singleton &other);  Prohibit assignment    Singleton ()  //Disallow creation of object    {        cout << "Singleton ..." << Endl;    }    Static Singleton *instance_;}; Singleton *singleton::instance_;int Main (void) {    //singleton s1;  Error, calling the default constructor    Singleton *s1 = Singleton::getinstance ();    Singleton *s2 = Singleton::getinstance ();    Singleton S3 (*S1);        Error, call copy constructor    return 0;}
Operation Result:Singleton ...


Although the above program calls two getinstance functions, it only calls the constructor once, that is, an object is created. Declare the assignment operator and copy constructor as private and prohibit copying . But one problem with the program is that the object's lifetime is not destroyed .


2, in order to solve the problem of the object will not be destroyed, you can use a static nested class object to solve:

#include <iostream>using namespace Std;class singleton{public:static Singleton *getinstance () {if (in        Stance_ = = NULL) {instance_ = new Singleton;    } return Instance_;    } ~singleton () {cout << "~singleton ..." << Endl;                } class Garbo {public: ~garbo () {if (Singleton::instance_! = NULL) {            Delete Instance_;  }}};p Rivate:singleton (const Singleton &other);  Place copy function in private, prohibit copy Singleton &operator= (const Singleton &other);    Prohibit Assignment Singleton ()//Disallow creation of object {cout << "Singleton ..." << Endl;    } static singleton* Instance_;    Static Garbo Garbo_; Using deterministic destruction of objects}; Singleton::garbo Singleton::garbo_;  singleton* Singleton::instance_;int Main (void) {//singleton S1;    Error, calling the default constructor Singleton *s1 = Singleton::getinstance ();    Singleton *s2 = Singleton::getinstance (); Singleton S3 (*S1); Error, call copy constructor return 0;}
Operation Result:Singleton ...
~singleton ...

Explanation: The deterministic destructor of a statically nested object invokes the destructor of the Garbo class and deletes a pointer to the Singleton class within the destructor.


3, the above method is more cumbersome, you can also return the local static object reference to solve:

#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);  Place copy function in private, prohibit copy    Singleton &operator= (const Singleton &other);  Prohibit assignment    Singleton ()  //Disallow creation of object    {        cout << "Singleton ..." << Endl;    }}; int main (void) {    singleton& S1 = singleton::getinstance ();    singleton& s2 = singleton::getinstance ();    return 0;}
Running Result: Singleton ...
~singleton ...

Explanation: A local static object is initialized only once, so calling multiple getinstance functions gets the same object. because a static object is used within a function, it is not thread-safe.


4, can actually use the AUTO_PTR smart pointer to solve, the program is as follows, more detailed on the auto_ptr will be discussed in the following.

#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;}
Operation Result:
Singleton ...
~singleton ...

5, a hungry man type singleton mode (initialization is done at class load, so class load is slow, but object gets faster)

In fact, all of the singleton pattern examples above are not thread-safe, assuming that if two threads run to the statement if (instance = = null)at the same time, the instance does not create , then two threads will create an instance. If you do not want the lock to be thread safe, you can use the A Hungry man mode (that is, before the main function as an instance):

#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_;  }}};p Rivate:singleton (const Singleton &other);  Place copy function in private, prohibit copy Singleton &operator= (const Singleton &other);    Prohibit Assignment Singleton ()//Disallow creation of object {cout << "Singleton ..." << Endl;    } static const singleton* Instance_;    Static Garbo Garbo_; Using deterministic destructor of object};const singleton* singleton::instance_ = new Singleton ();  Singleton::garbo Singleton::garbo_;int Main (void) {//singleton S1;    Error, calling the default constructor const Singleton *S1 = Singleton::getinstance ();    Const Singleton *S2 = Singleton::getinstance ();        Singleton S3 (*S1); Error, call copy constructor   return 0;} 

Operation Result:
Singleton ...
~singleton ...


6, or through the lock way to achieve, detailed will be discussed in the following.


Second, const member function, const object, mutable modifier

1. CONST member function

The const member function does not modify the state of an object

The const member function can only access the value of a data member and cannot modify it


2. Const Object

If you designate an object as const, tell the compiler not to modify it
Definition of a Const object:

Const Class Name Object name (parameter table);

Const object cannot call non-const member function


3, mutable decoration

Data members decorated with mutable can be modified even if they are in a const object or in a 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_ = +;  Error, attempting to modify 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 (ten);    T.getx ();    Test T2 (+);    T2. GetX ();    T.output ();    T.output ();    cout << t.getoutputtimes () << Endl;    return 0;}
Operation Result:

Const GetX ...
GetX ...
x=10
x=10
2



Reference:

C + + Primer Fourth Edition
Effective C + + 3rd

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

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

C + + Programming specification

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

C + + Primer Learning Notes _24_ class and Data Abstraction (--static) with singleton mode, auto_ptr and singleton mode, const member function, const object, mutable modifier

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.