C++简明图解分析静态成员与单例设计模式

目录
  • 静态成员概述
  • 静态成员数据
  • static修饰静态成员函数
  • const修饰静态成员
  • const修饰成员函数
  • 静态成员案例
  • 单例模式

静态成员概述

1、静态成员包括静态成员数据、静态成员函数

2、成员数据、成员函数被 static修饰 就叫静态成员数据、静态成员函数

3、不管这个类创建了多少个对象,静态成员只有一份,这一份被所有属于这个类的对象共享。

4、静态成员 是属于类 而不是具体的某个对象。

5、静态成员 是在定义完类的时候 就存在了。

静态成员数据

静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。

静态成员变量必须在类中声明,在类外定义。

静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间。

class Data
{
public:
    int num;//普通成员变量
    static int data;//静态成员变量(类内声明)
};
//定义的时候 不需要加static
int Data::data=100;//类外定义+初始化
void test01()
{
    //data是静态成员变量 是属于类 可以通过类名称::直接访问
    cout<<Data::data<<endl;//100
    //赋值
    Data::data = 200;
    cout<<Data::data<<endl;//200
    //data静态变量 是所有对象 共享的 可以通过对象名访问
    Data ob1;
    ob1.data = 300;
    cout<<Data::data<<endl;//300
    Data ob2;
    cout<<ob2.data<<endl;//300
    //普通成员变量 属于对象的 只能通过对象名访问
    ob1.num = 100;
    cout<<"ob2.num = "<<ob2.num<<endl;//随机值
    //cout<<Data::num<<endl;//普通成员变量不能通过类名称访问
}

static修饰静态成员函数

静态成员函数:只能访问私有静态数据

引出:

class Data
{
private:
    int num;//普通成员变量
    static int data;//静态成员变量(类内声明)
public:
    //普通成员函数 依赖于 对象的 必须对象调用
    int getData(void)
    {
        return data;
    }
};
//定义的时候 不需要加static
int Data::data=100;//类外定义+初始化
void test01()
{
    //cout<<Data::data<<endl;//err 静态data是私有的 类外不能直接访问
    //cout<< Data::getData()<<endl;//err getData() 必须对象调用
    Data ob;
    cout<<ob.getData()<<endl;
    //存在问题:data静态的 在创建对象之前 就已经存在
    //如果类没有实例化对象 难道 就不能使用data了吗?
    //解决上述问题 就要用到静态成员函数
}

静态成员函数:

class Data
{
private:
    int num;//普通成员变量
    static int data;//静态成员变量(类内声明)
public:
    //普通成员函数 依赖于 对象的 必须对象调用
    int getData(void)
    {
        return data;
    }
    //静态成员函数  属于类 而不属于对象
    static int getDataStatic(void)
    {
        return data;
    }
};
//定义的时候 不需要加static
int Data::data=100;//类外定义+初始化
void test01()
{
    //cout<<Data::data<<endl;//err 静态data是私有的 类外不能直接访问
    //cout<< Data::getData()<<endl;//err getData() 必须对象调用
    Data ob;
    cout<<ob.getData()<<endl;
    //存在问题:data静态的 在创建对象之前 就已经存在
    //如果类没有实例化对象 难道 就不能使用data了吗?
    //解决上述问题 就要用到静态成员函数
    //1、静态成员函数 属于类 就可以通过类名称直接访问
    cout<<Data::getDataStatic()<<endl;
    //2、也可以通过对象名访问(对象共享静态成员函数)
    cout<<ob.getDataStatic()<<endl;
}

注意:

1、静态成员函数的目的 操作静态成员数据。

2、静态成员函数 不能访问 非静态成员数据。(静态成员函数内部没有this指针)

3、普通成员函数 可以操作 静态成员数据 非静态成员数据。

4、静态成员变量 和 静态成员函数 都有权限之分。

const修饰静态成员

如果一个类的成员,既要实现共享,又要实现不可改变,那就用 static const 修饰

class Data
{
public:
    const static int data;//静态成员变量(类内声明)
public:
    //静态成员函数  属于类 而不属于对象
    static int getDataStatic(void)
    {
        //num = 200;//err 静态成员函数 不能访问普通成员变量
        return data;
    }
};
//定义的时候 不需要加static
const int Data::data=100;//类外定义+初始化
void test02()
{
    //访问
    cout<<Data::data<<endl;
    //赋值
    //Data::data = 200;//err data静态成员只读
    cout<<Data::data<<endl;
}

const修饰对象 叫常对象

const int num = 10;//系统不会给num开辟空间 num被放入符号表中 如果后期对&num 这时系统才会给num开辟空间

class Data
{
private:
    int data;
    mutable int num;
public:
    //遍历 成员的函数 不会去修改成员的值
    //如果函数不会更改成员数据 就让编译器知道 这是一个const函数
    void myPrintData(void) const
    {
        //data =10000;//err const修饰函数 函数不能操作普通成员变量
        cout<<this->data<<endl;
        //cout<<data<<endl;
        //mutable修饰的成员变量 可以修改
        num = 200;
    }
    //编译器认为 普通成员函数 存在修改成员变量 可能
    void setData(int data) const
    {
        //this->data = data;
        return;
    }
    Data()
    {
        cout<<"无参构造"<<endl;
    }
    Data(int data)
    {
        this->data =data;
        cout<<"有参构造"<<endl;
    }
    Data(const Data &ob)
    {
        this->data = ob.data;
        cout<<"拷贝构造"<<endl;
    }
    ~Data()
    {
        cout<<"析构函数"<<endl;
    }
};
void test03()
{
    //常对象
    const Data ob1(200);
    //常对象 只能调用const修饰的函数 遍历成员数据
    ob1.setData(20000);
    ob1.myPrintData();
}

运行结果:

const修饰成员函数

用const修饰的成员函数时,const修饰this指针指向的内存区域,成员函数体内不可以修改本类中的任何普通成员变量, 当成员变量类型符前用mutable修饰时例外。

int myFun(void) const //const修饰的是成员函数
{}//函数内部不能修改 普通成员变量  mutable修饰时例外
class Data2
{
public:
    int a;
    mutable int b;
public:
    Data2(int a, int b):a(a),b(b)
    {
//        this->a = a;
//        this->b = b;
    }
    //const修饰的是整个成员函数 表明在函数内部只能对数据成员 读操作
    void showData2(void) const
    {
        //a=100;//err
        //如果在const修饰的成员函数中 修改成员数据的值 请事先对成员数据进行mutable修饰
        b = 200;//ok
        cout<<"a="<<a<<", b="<<b<<endl;
    }
};
void test02()
{
    Data2 ob(10,20);
    ob.showData2();
}

静态成员案例

案例1:静态成员 统计类 实例化对象的 个数

#include <iostream>
using namespace std;
class Data
{
public:
    Data()
    {
        cout<<"无参构造"<<endl;
        count++;
    }
    Data(const Data &ob)
    {
        cout<<"拷贝构造函数"<<endl;
        count++;
    }
    ~Data()
    {
        count--;
        cout<<"析构函数"<<endl;
    }
    static int count;
};
int Data::count = 0;
int main(int argc, char *argv[])
{
    Data ob1;
    Data ob2;
    {
        Data ob3;
        Data ob4;
        cout<<"对象的个数:"<<Data::count<<endl;
    }
    cout<<"对象的个数:"<<Data::count<<endl;
    return 0;
}

运行结果:

单例模式

单例模式 所设计的类 只能实例化一个对象。

单例模式的步骤:

1、不允许Printer实例对象(把构造、拷贝构造函数私有化)

2、定义一个静态对象指针 保存唯一的对象地址

3、定义一个静态 成员函数 拿到唯一的对象的地址 方便外界使用

案例:

单例模式设计--打印机(重要)

步骤1:在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例

步骤2:提供一个公共静态的方法,让客户可以访问它的唯一实例。

步骤3:为了防止在外部对实例化其他对象,将其默认构造函数和拷贝构造函数设计为私有

#include <iostream>
using namespace std;
class Printer
{
public:
    //2、提供一个方法 获得单例指针
    static Printer* getSignlePrint(void)
    {
        return signlePrint;
    }
    //4、设置功能函数(自定义)
    void printText(char *str)
    {
        cout<<"打印"<<str<<endl;
        count++;
    }
    int count;
private:
    //1、定义一个静态的 对象指针变量 保存唯一实例地址
    static Printer *signlePrint;
private:
    //3、防止 该类实例化其他对象 将构造函数全部 私有
    Printer(){count=0;}
    Printer(const Printer &ob){}
};
Printer *Printer::signlePrint = new Printer;
int main(int argc, char *argv[])
{
    //打印任务1
    Printer *p1 = Printer::getSignlePrint();
    p1->printText("入职报告1");
    p1->printText("体检报告2");
    p1->printText("离职证明3");
    //打印任务2
    Printer *p2 = Printer::getSignlePrint();
    p2->printText("入职报告1");
    p2->printText("体检报告2");
    p2->printText("离职证明3");
    cout<<"打印任务数量:"<<p2->count<<endl;
    return 0;
}

运行结果:

到此这篇关于C++简明图解分析静态成员与单例设计模式的文章就介绍到这了,更多相关C++静态成员内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++和java设计模式之单例模式

    单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点.其构造过程由自身完成,可以将构造方法定义为private型的,这样外界就只能通过定义的静态的函数Instance()构造实例,这个函数的目的就是返回一个类的实例,在此方法中去做是否有实例化的判断.客户端不再考虑是否需要去实例化的问题,把这些都交给了单例类自身.通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法,就是让类自身负责保存它的唯一实例.这个类可以保证没有其他实例可

  • C++的静态成员变量和静态成员函数详解

    目录 一.static修饰变量 二.static修饰函数 三.static在类中使用 1.创建与初始化 2.使用问题 3.在public.private下static变量使用 四.class含有static变量所占空间 五.练习题:求学生总人数.总分.平均分系统. 总结 static int a = 10;//在静态区分配空间,不在堆栈 在静态区分配空间,不在堆栈分配空间.因此,只有等到所以函数全部执行完成后,才会释放空间. 一.static修饰变量 void text() { static i

  • 详解c++ 静态成员变量

    类定义时的静态成员只是声明,静态成员的定义和初始化要在类之外完成 C++的static关键字可修饰类成员变量/方法,表示变量/方法不从属于特定对象,而是属于类的.仔细琢磨静态成员变量,会发现其与C++的方式既相容也矛盾,具有特殊性. 先说相容的一面.·C/C++·有声明和定义的说法:声明给出签名,定义给出具体实现.对类型而言,声明不一定能知道其对象占用空间大小,但根据定义肯定能确定内存占用.说静态成员与C++方式是相容的,因为其初始化方式与方法的定义一致.下面是一个例子: // Foo.hpp

  • C++设计模式之单例模式

    问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进行写日志.那么,如何构造一个日志模块的实例呢?难道,每次new一个日志模块实例,写完日志,再delete,不要告诉我你是这么干的.在C++中,可以构造一个日志模块的全局变量,那么在任何地方就都可以用了,是的,不错.但是,我所在的开发部门的C++编码规范是参照Google的编码规范的. 全局变量在项目

  • C++类的静态成员变量与静态成员函数详解

    目录 1.类的静态成员变量 2.静态成员函数 总结 1.类的静态成员变量 C++类的静态成员变量主要有以下特性: 1.静态成员变量需要类内定义,类外初始化 2.静态成员变量不依赖于类,静态成员变量属于全局区,不属于类的空间. 3.静态成员变量通过类名访问,也可以通过对象访问,同一类的不同对象,静态成员共享同一份数据 下面通过代码验证以上三种说法: #include <iostream> using namespace std; class Base{ public: static int va

  • 老生常谈c++中的静态成员

    引言 有时候需要类的一些成员与类本身相关联,而不是与类的每个对象相关联.比如类的所有对象都要共享的变量,这个时候我们就要用到类的静态成员. 声明类的静态成员 声明静态成员的方法是使用static关键字. static成员可以是public也可以是private的. 例如,定义一个类表示银行的账户记录: class Account{ public: //其他非静态函数及数据成员 //静态函数 static double get_rate(){ return interestRate; } stat

  • C++设计模式之单例模式详解

    目录 单例模式:就是只有一个实例. 单例模式又分为两种基本的情形:饿汉式和懒汉式 如下是懒汉式单例类 小结: 继续看单例模式 总结 单例模式:就是只有一个实例. singleton pattern单例模式:确保某一个类在程序运行中只能生成一个实例,并提供一个访问它的全局访问点.这个类称为单例类.如一个工程中,数据库访问对象只有一个,电脑的鼠标只能连接一个,操作系统只能有一个窗口管理器等,这时可以考虑使用单例模式. 众所周知,c++中,类对象被创建时,编译系统为对象分配内存空间,并自动调用构造函数

  • C++简明图解分析静态成员与单例设计模式

    目录 静态成员概述 静态成员数据 static修饰静态成员函数 const修饰静态成员 const修饰成员函数 静态成员案例 单例模式 静态成员概述 1.静态成员包括静态成员数据.静态成员函数 2.成员数据.成员函数被 static修饰 就叫静态成员数据.静态成员函数 3.不管这个类创建了多少个对象,静态成员只有一份,这一份被所有属于这个类的对象共享. 4.静态成员 是属于类 而不是具体的某个对象. 5.静态成员 是在定义完类的时候 就存在了. 静态成员数据 静态变量,是在编译阶段就分配空间,对

  • C++单例设计模式详细讲解

    目录 特殊类设计 只能在堆上创建对象的类 请设计一个类只能在栈上创建对象 请设计一个类不能被拷贝 请设计一个类不能被继承 请设计一个类只能创建一个对象(单例模式) 懒汉模式和饿汉模式的对比 特殊类设计 只能在堆上创建对象的类 请设计一个类,只能在堆上创建对象 实现方式: 将类的构造函数私有,拷贝构造声明成私有.防止别人调用拷贝在栈上生成对象. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建 class test { public: static test* GetObj() { re

  • 完美解决单例设计模式中懒汉式线程安全的问题

    首先写个单例: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} public static SingleDemo getInstance(){ if(s == null){ s = new SingleDemo(); } return s; } } 写个测试类: public class ThreadDemo3 { public static void main(String

  • 浅谈JAVASE单例设计模式

    简单的说设计模式,其实就是对问题行之有效的解决方式.其实它是一种思想. 1.单例设计模式. 解决的问题:就是可以保证一个类在内存中的对象唯一性.(单个实例) 使用单例设计模式需求:必须对于多个程序使用同一个配置信息对象时,就需要保证该对象的唯一性. 如何保证对象唯一性?                                                      解决步骤: 1.不允许其他程序用new创建该对象.                                    

  • Python 单例设计模式用法实例分析

    本文实例讲述了Python 单例设计模式用法.分享给大家供大家参考,具体如下: demo.py(单例): class MusicPlayer(object): # 类属性 记录对象引用 instance = None def __new__(cls, *args, **kwargs): # 1. 判断类属性是否是空对象 if cls.instance is None: # 2. 调用父类的方法,为第一个对象分配空间 cls.instance = super().__new__(cls) # 3.

  • python单例设计模式实现解析

    这篇文章主要介绍了python单例设计模式实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 所谓单例,就是让类创建对象的时候,在系统中只有唯一的一个实例. (1)定义一个类属性,初始值是None,用于记录单例的引用. (2)重写__new__方法. (3)如果类属性是None,调用父类方法分配空间,并在属性中记录结果. (4)返回属性中记录的对象引用. class MusicPlayer(object): instance = None

  • Unity通用泛型单例设计模式(普通型和继承自MonoBehaviour)

    单例模式是设计模式中最为常见的,不多解释了.但应该尽量避免使用,一般全局管理类才使用单例. 普通泛型单例: public abstract class Singleton<T> where T : class, new() { private static T instance = null; private static readonly object locker = new object(); public static T Instance { get { lock (locker)

  • Java之单例设计模式示例详解

    单例设计模式 保证一个类在内存中只能有一个对象. 思路: 1)如果其他程序能够随意用 new 创建该类对象,那么就无法控制个数.因此,不让其他程序用 new 创建该类的对象. 2)既然不让其他程序 new 该类对象,那么该类在自己内部就要创建一个对象,否则该类就永远无法创建对象了. 3)该类将创建的对象对外(整个系统)提供,让其他程序获取并使用. 饿汉式: 一上来我就把对象给你 new 好了,你来了直接就可以拿去"吃"了 懒汉式 (要是有人问单例的延迟加载方式指的就是这种方式) 一开始

  • 浅析Java单例设计模式(自写demo)

    目录 单例模式特点 单例模式优点 实现方式 饿汉式(线程安全) 懒汉式 单例模式特点 1.构造器私有 2.在一个Java应用程序中,可保证只有一个实例对象 3.只提供一个供外界调用的getInstance()方法 单例模式优点 1.减少某些对象的频繁创建,降低系统开销和内存占用 2.外部调用不使用new关键字,降低系统内存的使用频率 3.对于特殊的类,在系统中只能存在一个实例,否则系统无法正常运行,比如Controller 实现方式 这里简单介绍两种实现方式 饿汉式(线程安全) /** * @a

  • 浅谈Java编程中的单例设计模式

    写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像findbugs等代码检查工具还会认为使用System.out.println()是一个bug. 为什么作为Java新手神器的System.out.println(),到了真正项目开发当中会被唾弃呢?其实只要细细分析,你就会发现它的很多弊端.比如不可控制,所有的日志都会在项目上线后照常打印,从而降低运

随机推荐