• 单例模式


    1.在阅读Android源代码的时候会发现,对于一个简单的问题,这些代码也设计的非常复杂,有各种类和各种嵌套,这些代码看起来一点都不直观,为的是让代码更加容易扩展,引入和很多设计模式。当理解了这些设计模式后再去看Android源代码就不会感觉那么复杂了。

    2.单例模式:在一个进程(包括一个进程的多个线程中),一个类只有一个实例化对象。

    3.为了防止使用的人不使用getInstance()获取单例对象,而是直接new或直接定义对象或直接使用g_singleton指针,可以把Singleton对象的构造函数设置为private的,把g_singleton设置成private的。

    4.限制:Singleton不可被继承,因为其构造函数是private的。

    5.单例模式实现方式
    (1)懒汉模式:用到时迫不得已才生成

    /*------C++实现--------*/
    #include <iostream>
    
    using namespace std;
    
    class Singleton {
    private:
        Singleton() { cout << "Singleton()" << endl; } /*构造函数是私有的*/
        static Singleton *g_singleton;
        static pthread_mutex_t mutex;
    public:
        static Singleton* getInstance();
    };
    
    pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
    Singleton *Singleton::g_singleton = NULL;
    
    Singleton* Singleton::getInstance() {
        if (g_singleton == NULL) {    //double check,提高效率
            pthread_mutex_lock(&mutex);
            if (g_singleton == NULL) {
                g_singleton = new Singleton(); //有没有()都是可以的。
            }
            pthread_mutex_unlock(&mutex);
        }
        return g_singleton;
    }
    
    int main() {
    
        Singleton *s1 = Singleton::getInstance();
        cout << s1 << endl;
        Singleton *s2 = Singleton::getInstance();
        cout << s1 << endl;
        Singleton *s3 = Singleton::getInstance();
        cout << s1 << endl;
    
        return 0;
    }
    /*------Java实现--------*/
    public class Singleton {  
        private volatile static Singleton singleton;  
        private Singleton (){}  
        public static Singleton getSingleton() {  
            if (singleton == null) {  
                synchronized (Singleton.class) {  
                    if (singleton == null) {  
                        singleton = new Singleton();  
                    }  
                }  
            }  
            return singleton;
        }  
    }

    (2)饿汉模式:很饿很急,一开始就实例化好
    C++: SingleTon *SingleTon::gInstance = new SingleTon; 定义的时候就生成。
    SingleTon::getInstance()中直接返回这个对象即可,此时就不需要锁了!

    /*------C++实现--------*/
    #include <iostream>
    
    using namespace std;
    
    class Singleton {
    private:
        Singleton() { cout << "Singleton()" << endl; }
        static Singleton *g_singleton;
    public:
        static Singleton* getInstance();
    };
    
    Singleton *Singleton::g_singleton = new Singleton();
    Singleton* Singleton::getInstance() {
        return g_singleton;
    }
    
    int main() {
    
        Singleton *s1 = Singleton::getInstance();
        cout << s1 << endl;
        Singleton *s2 = Singleton::getInstance();
        cout << s1 << endl;
        Singleton *s3 = Singleton::getInstance();
        cout << s1 << endl;
    
        AA a1;
    
        return 0;
    }
    /*------Java实现--------*/
    public class Singleton {
        private static Singleton instance = new Singleton();
        private Singleton (){}
        public static Singleton getInstance() {
            return instance;
        }
    }

    6.Java中的单例模式的实现

    class Singleton {
        private static Singleton g_single;
        private Singleton() {
            System.out.println("Singleton()");
        }
    
        public static Singleton instance() {
            if (g_single == null) {
                /*
                 * 1. 这里不能使用this,因为类的静
                 *    态成员不能访问非静态成员。
                 * 2. 使用synchronized来上锁,java中
                 *    可没有C++中的mutex.
                 */
                synchronized(Singleton.class) { 
                    if (g_single == null) {
                        g_single = new Singleton();
                    }
                }
            }
            return g_single;
        }
    }
    
    
    public class SingletonTest {
        public static void main(String args[]) {
            Singleton s1 = Singleton.instance();
            Singleton s2 = Singleton.instance();
            Singleton s3 = Singleton.instance();
    
            System.out.println("s1.hashCode() = " + s1.hashCode());
            System.out.println("s2.hashCode() = " + s2.hashCode());
            System.out.println("s3.hashCode() = " + s3.hashCode());
        }
    }

    7. Android中单例模式的使用

    Android中已经有封装好的,在system/core/include/utils/singleton.h中,可以按如下方法使用:

    //示例代码来自:
    frameworks/native/services/sensorservice/sensorDevice.h
    frameworks/native/services/sensorservice/sensorService.cpp
    
    //头文件
    #include <utils/Singleton.h>
    //定义类
    class SensorDevice : public Singleton<SensorDevice> {
        ...
    }
    //使用
    SensorDevice& dev(SensorDevice::getInstance());

    8. C++单例模式+类模板

    #include <iostream>
    #include <pthread.h>
    
    using namespace std;
    
    template <typename T>
    class Singleton {
    private:
        static T *g_single_t;
        static pthread_mutex_t lock;
        //它是一个类模板,根本不是类,不能直接实例化对象,所以不需要构造函数,
        //就算是定义了也始终不会调用。
        /*构造函数实现成private的,让你无法直接实例化对象*/
        // Singleton() {
        //     cout << "Singleton()" << endl;
        // }
    
    public:
        //类模板不需要构造/析构函数,定义了也不会调用,调用的是特例化的。
        // ~Singleton() {
        //     cout << "~Singleton()" << endl;
        // }
        
        static T * instance() {
            if (!g_single_t) {
                //优化了一下,减少上锁的次数
                pthread_mutex_lock(&lock);
                if (!g_single_t) {
                    g_single_t = new T();
                }
                pthread_mutex_unlock(&lock);
            }
            return g_single_t;    
        }
    };
    
    /*这是定义,当然要加上变量的类型*/
    template <typename T>
    T * Singleton<T>::g_single_t = NULL;
    template <typename T>
    pthread_mutex_t Singleton<T>::lock = PTHREAD_MUTEX_INITIALIZER;
    
    
    class Master {
    //这里的构造函数不能定义成私有的了
    public:
        Master() {
            cout << "Master()" << endl;
        }
    
        ~Master() {
            cout << "~Master()" << endl;
        }
    };
    
    
    
    class Person {
    //这里的构造函数不能定义成私有的了
    public:
        Person() {
            cout << "Person()" << endl;
        }
    
        ~Person() {
            cout << "~Person()" << endl;
        }
    };
    
    
    
    int main(void)
    {
        Master *m1 = Singleton<Master>::instance();
        Master *m2 = Singleton<Master>::instance();
        Master *m3 = Singleton<Master>::instance();
        cout << m1 << endl;
        cout << m2 << endl;
        cout << m3 << endl;
    
        Person *p1 = Singleton<Person>::instance();
        Person *p2 = Singleton<Person>::instance();
        Person *p3 = Singleton<Person>::instance();
        cout << p1 << endl;
        cout << p2 << endl;
        cout << p3 << endl;
        
        //即便特例化成普通类型的变量,Singleton的构造函数还是不会调用
        cout << "test int" << endl;
        int *i1 = Singleton<int>::instance();
        int *i2 = Singleton<int>::instance();
        int *i3 = Singleton<int>::instance();
        cout << i1 << endl;
        cout << i2 << endl;
        cout << i3 << endl;
        
        return 0;
    }
    /* # ./pp Master() 0x132f010 0x132f010 0x132f010 Person() 0x132f030 0x132f030 0x132f030 test int 0x132f050 0x132f050 0x132f050 */

    参考:http://www.runoob.com/design-pattern/singleton-pattern.html

  • 相关阅读:
    [MFC] MFC 用mciSendString加载WAV资源文件
    [JS] HTML QQ分享界面js代码
    [MFC] MFC 打开HTML资源(用ID版,也可加载到自己的web控件上)
    [ACM_暴力][ACM_几何] ZOJ 1426 Counting Rectangles (水平竖直线段组成的矩形个数,暴力)
    [ACM_动态规划] ZOJ 1425 Crossed Matchings(交叉最大匹配 动态规划)
    easyui combobox可编辑的情况下,只能首字母开始过滤的问题选项
    easyui-combobox绑定回车事件注意事项
    easyui-combobox绑定回车事件相关
    jquery-qrcode 生成和读取二维码
    zxing生成二维码和读取二维码
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10660462.html
Copyright © 2020-2023  润新知