首页 > 编程语言 >C++静态成员和单例模式

C++静态成员和单例模式

时间:2023-08-24 19:55:19浏览次数:47  
标签:变量 静态 成员 C++ 对象 Single 单例

一、静态成员

Ⅰ.什么是静态成员:

被static修饰的成员变量和成员函数就叫静态成员

Ⅱ.普通成员的特点:
  • 成员变量:每个类对象中都有一份属于自己的成员变量,相互之间没有关联、独立的

  • 成员函数:隐藏着一个this指针,接收调用者的地址用于区分调用者

Ⅲ.静态成员的特点:
  • 静态成员变量:
    ①存储在data或bss内存段中,一个类中的所有静态成员变量只有唯一一份,被所有类对象共享
    ②一旦成员变量被声明为静态成员变量后,通过sizeof计算类字节数时,就不统计该变量的字节数
    ③静态成员变量必须在类内加static声明,在类外单独定义、初始化,定义时无需加static
    ④静态成员变量的生命周期不再依赖于某个对象,伴随整个程序的生命周期
    ⑤因为静态成员变量的存在不依赖于任何类对象,所以可以无需实例化类对象,直接访问静态成员变量

     类名::静态成员变量     (无需实例化对象,但是一般成员变量都是私有的)
     对象名.成员变量/静态成员变量
     对象名.成员变量/静态成员变量
    
  • 静态成员函数:
    ①没有隐藏的this指针,所以在静态成员函数中无法直接访问普通成员变量、普通成员函数,但是可以手动传递对象的地址来间接访问,毕竟静态成员函数还是属于类的
    ②但是可以直接访问静态成员变量、静态成员函数
    ③调用方式

     类名::静态成员函数()   (无需实例化对象)
     对象名.成员函数()/静态成员函数()
     对象名.成员函数()/静态成员函数()
    
Ⅳ.静态成员的作用
  1. 静态成员相当于多了一层类作用域的全局变量、全局函数

  2. 静态成员变量适合存储所有类对象的公共属性,从而节约资源(税率、利率等)

  3. 静态成员函数可以当做访问私有的静态成员变量的公开接口,一方面不破坏类的封装性,另一方面可以无需实例化对象也能调用类的静态成员,让类本身具有管理自己成员的能力

常见面试题
  • C和C++中的static的区别?

二、单例模式(考点)

  • 什么是单例模式:
    只能实例化一个类对象

  • 什么场景下使用单例模式:
    进程管理器、日志管理器、网站访问计数器、应用配置程序、线程池、服务器的连接管理器

Ⅰ.实现单例模式的原理:
  1. 禁止在类外随意实例化对象,把构造函数\拷贝构造私有化

  2. 确保类对象只有一份,在类中定义一个静态的类对象成员变量

  3. 提供一个获取静态类对象成员变量的公开的接口,设计一个静态成员函数用于获取那唯一的一个静态类对象

Ⅱ.饿汉模式的单例:(
  • 程序运行开始时就立即实例化单例类对象,不管后期是否用得到都会完成实例化

  • 优点:不可能被多个线程同时运行创建多份(线程安全)

  • 缺点:如果后期使用不到,就浪费时间、资源

Ⅲ.懒汉模式的单例:(
  • 什么时候使用,什么时候才去实例化单例类对象

  • 优点:使用时才会创建,节约时间、资源

  • 缺点:可能会被多个线程同时实例化,有可能会创建出多个单例类对象(线程不安全)

常考笔试题:实现饿汉、懒汉模式的单例,线程安全的懒汉模式的单例
  • 饿汉单例模式

    #include <iostream>
    using namespace std;class Single
    
    {
        static Single obj;
        Single(void)
        {
            cout << "我是构造函数" << endl;
        }
        Single(const Single& that)
        {
            cout << "我是拷贝构造" << endl;
        }
    public:
        static Single& getobj(void)
        {
            return obj;
        }
        void show(void)
        {
            cout << &obj << endl;
        }
    };
    
    Single Single::obj;
    
    int main(int argc,const char* argv[])
    {
        Single& s = Single::getobj();
        s.show();
        Single& s1 = Single::getobj();
        s1.show();
    }
    
  • 懒汉单例模式

    #include <iostream>
    using namespace std;
    
    class Single
    {
        static Single* obj;
        Single(void)
        {
            cout << "我是构造函数" << endl;
        }
        Single(const Single& that)
        {
            cout << "我是拷贝构造" << endl;
        }
    public:
        static Single& getobj(void)
        {
            if(obj == NULL)
            {
                obj = new Single;
            }
            return *obj;
        }
        void show(void)
        {
            cout << &obj << endl;
        }
    };
    
    Single* Single::obj;
    
    int main(int argc,const char* argv[])
    {
        Single& s = Single::getobj();
        s.show();
        Single& s1 = Single::getobj();
        s1.show();
    }
    
  • 线程安全的懒汉单例模式

    #include <iostream>
    #include <pthread.h>
    using namespace std;
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    class Single
    {
    	static Single* obj;
    	Single(void)
    	{
    		cout << "我是构造函数" << endl;	
    	}
    	Single(const Single& that)
    	{
    		cout << "我是拷贝构造" << endl;	
    	}
    public:
    	static Single& get_obj(void)
    	{
    		if(NULL == obj)
    		{
    			obj = new Single;	
    		}
    		return *obj;	
    	}
    
    	void show(void)
    	{
    		cout << obj << endl;	
    	}
    };
    
    Single* Single::obj;	
    
    void* run(void* arg)
    {
    	pthread_mutex_lock(&mutex);
    	Single& s = Single::get_obj();
    	pthread_mutex_unlock(&mutex);
    }
    
    int main(int argc,const char* argv[])
    {
    	pthread_t tid[20];
    	for(int i=0; i<20; i++)
    	{
    		pthread_create(&tid[i],NULL,run,NULL);	
    	}
    	for(int i=0; i<20; i++)
    	{
    		pthread_join(tid[i],NULL);	
    	}
    }
    

标签:变量,静态,成员,C++,对象,Single,单例
From: https://www.cnblogs.com/wangqiuji/p/17655026.html

相关文章

  • C++对象的创建和销毁过程分析
    对象的创建和销毁过程分析1、对象的创建过程①给对象划分内存空间(栈、堆)②执行初始化列表根据继承表的顺序调用父类的无参构造或有参构造通过:父类(val)调用父类的有参构造根据成员变量的定义顺序调用类类型成员的无参构造或有参构造通过:类类型成员名(val)调用类类型成员......
  • C++面向对象、类和对象、访问控制限定符
    面向对象和面向过程面向过程:关注如何解决问题,以及解决问题的步骤面向对象:关注的解决问题的"人"即"对象",以及实现能解决问题的"对象"注意:面向对象的细节的本质上还是面向过程,因此面向对象不是解决问题的捷径,而是以更高的维度去思考问题面向对象的四个特性:抽象:先找出(想象)......
  • Windows中通过C++自动添加防火墙例外规则
    在C++程序中无法直接控制防火墙警报窗口的显示,因为这是由操作系统和防火墙软件控制的。防火墙警报窗口是为了提醒用户程序正在尝试与外部网络进行通信,以确保用户意识到可能的网络活动。然而,可以通过编写C++程序在用户的系统上自动添加防火墙例外规则,从而避免防火墙警报窗口的显示......
  • 单例模式——继承使用方式
    namespaceFeng.FramWorkDesign{publicclassSingleton<T>whereT:Singleton<T>{privatestaticTmInstance;publicstaticTMInstance{get{if(mInstance==null)......
  • 基于静态编译构建微服务应用
    作者:饶子昊(铖朴)Java的局限性传统的一个Java应用从代码编写到启动运行大致可以分为如下步骤:首先,编写.java源代码程序。然后,借助javac工具将.java文件翻译为.class的字节码,字节码是Java中非常重要的内容之一,正是因为它的出现,Java才实现对底层环境的屏蔽,达到Writ......
  • 单例模式——懒汉模式
    1、定义:单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点。懒汉式单例模式是指在第一次访问时才创建唯一实例,这种实现方式在实例创建开销较大或者实例使用不频繁时,可以减少不必要的资源开销。但在多线程环境下,懒汉式单例模式的实现需要加上synchronize......
  • C++构造函数、析构函数、初始化列表
    构造函数构造函数就是与类名同名的成员函数,当实例化对象时它会自动执行,当构造函数执行结束后,对象才完成实例化任务:一般负责对类对象进行初始化、资源分配class类名{int*p;public:类名(参数){p=newint;}}......
  • 依赖注入的单例模式对性能的影响及性能优化方法的思考
    摘要: 大概一年前开始在思考构造函数中依赖注入较多,这对系统性能及硬件资源消耗产生一些优化想法。一般较多公司的项目都使用Autofac 依赖注入(Scoped作用域),但是发现过多的对象产生会消耗 CPU,内存并给GC(垃圾回收)造成一定的压力。那么开始思考是否能够使用单例(Singl......
  • C++内联函数、引用、强制类型转换
    三、内联函数inline1、普通函数普通函数会被编译成二进制指令存储在代码段中,调用语句会生成一条跳转指令,当程序运行到调用语句时,会跳转该函数在代码段中对应的位置执行,执行结束会返回2、什么是内联函数内联函数也会被翻译成二进制指令,但调用语句不会生成跳转指令,而是直接把内......
  • 在Windows系统中搭建C++刷算法题环境
    下载Docker首先,到Docker官方网站下载适合Windows系统的DockerDesktop并安装。下载Ubuntu镜像使用如下命令安装Ubuntu最新镜像:dockerpullubuntu在镜像中搭建C++编译环境使用如下命令启动一个ubuntu容器:dockerrun-itd--nameubt-cpp-v/d/code/algo:/dataubuntu使......