C++学习之静态成员和单例模式

  1. 静态成员变量

     class 类名{
     		static 数据类型 变量名;//声明
     };
    

    数据类型 类名::变量名 = 初值;//定义和初始化
    1)普通成员变量属于对象,而静态成员变量不属于对象,静态成员变量内存在数据段(全局区)(sizeof(类名)会发现,静态成员不计入总大小),可以把静态成员变量理解为是被限制在类的内部去使用的全局变量.
    2)普通成员变量需要在构造定义和初始化,而静态成员变量需要在类的外部单独定义和初始化
    3)使用方法
    类名::静态成员变量;//推荐
    对象名.静态成员变量;//和上面等价

    class A{
    public:
        //普通成员变量在构造时定义和初始化
        A(int data = 0):m_data(data){}
        int m_data;//声明普通成员变量
        static int s_data;//声明静态成员变量
    
        //const和static同时修饰的成员变量,需要在声明
        //时初始化(特殊,了解)
        const static int cs_data = 0;//ok
    };
    //静态成员变量需要在类的外部单独定义和初始化
    int A::s_data = 20;
    
  2. 静态成员函数

    class 类名{
    	static 返回类型 函数名(形参表){
    		函数体;
    	}
    };
    

    1)静态成员函数没有this指针,也没有常属性,可以把它理解为是被限制在类的内部使用的全局函数。
    2)使用方法
    类名::静态成员函数(实参表);//推荐
    对象名.静态成员函数(实参表);//和上面等价

    注:在静态成员函数中只能访问静态成员,在非静态成员函数中既可以访问静态成员,也可以访问非静态成员.

    class A{
    public:
        A(void):m_data(10){}
        static void func1(void){
            cout << "静态成员函数" << endl;
            //cout << m_data << endl;//error
            cout << s_data << endl;
        }
        void func2(void) const {
            cout << "非静态成员函数" << endl;
            cout << m_data << endl;
            cout << s_data << endl;
        }
        int m_data;
        static int s_data;
    };
    int A::s_data = 20;
    
  3. 单例模式
    1)概念
    一个类只允许存在唯一的对象,并提供它的访问方法

    2)实现思路
    –》禁止在类的外部创建对象:私有化构造函数
    –》类的内部维护唯一的对象:静态成员变量
    –》提供单例对象的访问方法:静态成员函数

    3)创建方式
    –》饿汉式:单例对象无论用或不用,程序启动即创建
    优点:代码实现简单,多线程安全,访问使用效率高
    缺点:浪费内存

    –》懒汉式:单例对象用时再创建,不用即销毁
    优点:节省内存
    缺点:访问使用效率低,多线程中需要加锁保护,代码实现复杂

    饿汉式

    #include <iostream>
    using namespace std;
    //单例模式:饿汉式
    class Singleton{
    public:
        //3)使用静态成员函数获取单例对象
        static Singleton& getInstance(void){
            return s_instance;
        }
        void print(void) const{
            cout << m_data << endl;
        }
    private:
        //1)私有化构造函数
        Singleton(int data):m_data(data){
            cout << "单例对象被创建了" << endl;
        }
        //将缺省的拷贝构造函数声明为私有
        Singleton(const Singleton&);
        //2)使用静态成员变量来维护唯一的对象
        static Singleton s_instance;//声明
    private:
        int m_data;
    };
    Singleton Singleton::s_instance(123);//定义
    int main(void){
        //Singleton s(123);
        //Singleton* ps = new Singleton(123);
        cout << "main开始运行" << endl;
        Singleton& s1 = Singleton::getInstance();
        Singleton& s2 = Singleton::getInstance();
        Singleton& s3 = Singleton::getInstance();
        s1.print();
        s2.print();
        s3.print();
        cout << "&s1=" << &s1 << endl;
        cout << "&s2=" << &s2 << endl;
        cout << "&s3=" << &s3 << endl;
        
        //Singleton s4 = s1;//拷贝构造,应该error
        //cout << "&s4=" << &s4 << endl;
    
        return 0;
    }
    

    在这里插入图片描述 

    懒汉式

    #include <iostream>
    #include <pthread.h>
    using namespace std;
    //单例模式:懒汉式
    class Singleton{
    public:
        //3)使用静态成员函数获取单例对象
        static Singleton& getInstance(void){
            pthread_mutex_lock(&mutex);//加锁
            if(s_instance == NULL){
                s_instance = new Singleton(123);
            }
            ++s_count;//s_count = s_count + 1
            pthread_mutex_unlock(&mutex);//解锁
            return *s_instance;
        }
        //单例对象不用即销毁
        //所有的使用者都不再使用,才能销毁
        void release(void){
            pthread_mutex_lock(&mutex);//解锁
            if(--s_count == 0){
                delete s_instance;
                s_instance = NULL;
            }
            pthread_mutex_unlock(&mutex);//解锁
        }
        void print(void) const{
            cout << m_data << endl;
        }
    private:
        //1)私有化构造函数
        Singleton(int data):m_data(data){
            cout << "单例对象被创建了" << endl;
        }
        //将缺省的拷贝构造函数声明为私有
        Singleton(const Singleton&);
        //析构函数
        ~Singleton(void){
            cout << "单例对象被销毁了" << endl;
        }
    
        //2)使用静态成员变量来维护唯一的对象
        static Singleton* s_instance;//声明
        //计数:记录单例对象使用者的个数
        static int s_count;
        //互斥锁
        static pthread_mutex_t mutex;
    private:
        int m_data;
    };
    Singleton* Singleton::s_instance = NULL;
    int Singleton::s_count = 0;
    //定义和初始化互斥锁
    pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
    
    
    int main(void){
        //Singleton s(123);
        //Singleton* ps = new Singleton(123);
        cout << "main开始运行" << endl;
        //++s_count:1,new
        Singleton& s1 = Singleton::getInstance();
        //++s_count:2
        Singleton& s2 = Singleton::getInstance();
        //++s_count:3
        Singleton& s3 = Singleton::getInstance();
        s1.print();
        s1.release();//--s_count:2
    
        s2.print();
        s3.print();
        cout << "&s1=" << &s1 << endl;
        cout << "&s2=" << &s2 << endl;
        cout << "&s3=" << &s3 << endl;
        s2.release();//--s_count:1
        s3.release();//--s_count:0,delete
    
        return 0;
    }
    
    

    在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值