手撕code(2)

news2024/11/25 2:55:09

文章目录

  • 1 设计模式
    • 1.1 单例模式
      • 1.1.1 懒汉单例
      • 1.1.2 饿汉单例
      • 1.1.3 总结
    • 1.2 简单工厂模式
  • 2 实现智能指针


1 设计模式

1.1 单例模式

某个类,不应该有多个实例,此时就可以使用单例模式。如果尝试创建多个实例,编译器就会报错。

1.1.1 懒汉单例

像一个懒汉一样,需要用到创建实例了程序再去创建实例,不需要创建实例程序就“懒得”去创建实例,这是一种时间换空间的做法,这体现了“懒汉的本性”。
使用懒汉模式来实现,Singleton类被加载的时候,不会立刻实例化,等到第一次使用这个实例的时候,再实例化。

#include <iostream>

class Singleton {
public:
    static Singleton* getInstance() {
        cout << "SingleTon::getInstance()" << endl;
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }

private:
    static Singleton* instance;

    Singleton() {
        std::cout << "Singleton()" << std::endl;
    }

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

Singleton* Singleton::instance = nullptr;    // 懒汉

int main() {
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();

    // 输出的实例地址相同,说明只有一个实例被创建
    std::cout << "singleton1 address: " << singleton1 << std::endl;
    std::cout << "singleton2 address: " << singleton2 << std::endl;

    return 0;
}

1.1.2 饿汉单例

像一个饿汉一样,不管需不需要用到实例都要去创建实例,即在类产生的时候就创建好实例,这是一种空间换时间的做法。
作为一个饿汉而言,体现了它的本质——“我全都要”。
简易写法

class Singleton {
private:
    static Singleton* instance; // 静态成员变量,存储唯一的实例

    // 私有构造函数,防止外部实例化
    Singleton() {}

public:
    // 静态成员函数,用于获取实例
    static Singleton* getInstance() {
        return instance;
    }

    // 其他成员函数和成员变量
};

// 初始化静态成员变量
Singleton* Singleton::instance = new Singleton();

#include <iostream>

class SingleTon {
public:
    static SingleTon* getInstance() {
    	cout << "SingleTon::getInstance()" << endl;
        return instance;
    }

private:
    static SingleTon* instance;

    SingleTon() {
        std::cout << "SingleTon()" << std::endl;
    }

    SingleTon(const SingleTon&) = delete;
    SingleTon& operator=(const SingleTon&) = delete;
};

// 在类外进行静态成员变量的定义和初始化
SingleTon* SingleTon::instance = new SingleTon();

int main() {
    SingleTon* p1 = SingleTon::getInstance();
    SingleTon* p2 = SingleTon::getInstance();
    SingleTon* p3 = SingleTon::getInstance();

    // 在这里使用实例进行操作

    return 0;
}

Singleton 类通过一个静态成员变量 instance 存储唯一的实例。该实例在类加载时就被创建,并通过静态成员函数 getInstance() 返回。因为该实例在类加载时就创建,所以可以在任何时候通过 getInstance() 获取到同一个实例。
只要严格使用getInstance,就不会出现其他实例。

1.1.3 总结

懒汉式单例模式和饿汉式单例模式是两种常见的单例设计模式,它们的区别在于实例的创建时机和线程安全性。

1 创建时机:
懒汉式单例模式:在第一次使用时才创建实例。在 getInstance() 方法中进行判断,如果实例尚未创建,则创建一个实例并返回。懒汉式单例模式在程序启动时不会创建实例,而是在需要时才创建,也被称为延迟加载。
饿汉式单例模式:在类加载时就创建实例。在类的静态成员变量初始化时就创建了一个实例,并在 getInstance() 方法中直接返回该实例。饿汉式单例模式在程序启动时就会创建实例,无论是否被使用。

2 线程安全性:
懒汉式单例模式:默认情况下是线程不安全的。在多线程环境下,如果多个线程同时调用 getInstance() 方法并且实例尚未创建,则可能会创建多个实例。需要进行额外的线程安全措施,如加锁或使用双重检查锁定(Double-Checked Locking)来保证只有一个实例被创建。
饿汉式单例模式:默认情况下是线程安全的。在类加载时就创建了实例,所以不会存在多个线程同时创建实例的问题。无需额外的线程安全措施。
在这里插入图片描述

1.2 简单工厂模式

#include<iostream>
using namespace std;

typedef enum Type {
    type1,
    type2
} Type;

class product {
public:
    virtual void show() = 0;
    virtual ~product() = 0;
};
product::~product() {}

class productA : public product{
public:
    void show() {
        cout << "productA" << endl;
    }
    ~productA() override {
        cout << "~productA" << endl;
    }
};

class productB : public product{
public:
    void show() override {
        cout << "productB" << endl;
    }
    ~productB() override {
        cout << "~productB" << endl;
    }
};

class Factory {
public:
    product *Create(enum Type type) {
        switch(type) {
            case type1:
                return new productA();
            case type2:
                return new productB();
            default:
                return nullptr;
        }
    }
};

int main() 
{
    Factory factory;
    factory.Create(type1)->show();
    factory.Create(type2)->show();

    return 0;
}

2 实现智能指针

C++11中提供了三种智能指针,使用这些智能指针时需要引用头文件<memory>

std::shared_ptr:共享的智能指针
采用引用计数的方法,允许多个智能指针指向同一个对象,指向该对象的所有智能指针内部的引用计数会加1,每减少一个智能指针指向对象时引用计数减一,当引用计数为0时自动析构

std::unique_ptr:独占的智能指针
std::unique_ptr是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针,可以通过它的构造函数初始化一个独占智能指针对象,但是不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr。

std::weak_ptr:弱引用的智能指针,它不共享指针,不能操作资源,是用来监视shared_ptr的。
弱引用智能指针std::weak_ptr可以看做是shared_ptr的助手,它不管理shared_ptr内部的指针。std::weak_ptr没有重载操作符*和->,因为它不共享指针,不能操作资源,所以它的构造不会增加引用计数,析构也不会减少引用计数,它的主要作用就是作为一个旁观者监视shared_ptr中管理的资源是否存在。
共享指针详解

实现智能指针:
利用栈上的对象出作用域自动析构的特征,采用了栈上面的指针去管理堆上面的内容

//不带引用计数智能指针
#include <iostream>

using namespace std;

template<typename T>
class SmartPtr {
public:
    SmartPtr(T* ptr = nullptr) : _mptr(ptr) {}
    ~SmartPtr() { delete _mptr; }
    T& operator*() { return *_mptr; }//传引用 传值 传*_mptr
    T* operator->() { return _mptr; }//传指针 传_mptr;
private:
    T* _mptr;
};

class Test {
public:
    void test() { cout << "call Test::test" << endl; }
};

int main() {
    SmartPtr<int> ptr1(new int);
    *ptr1 = 20;
    cout << *ptr1 << endl;

    SmartPtr<Test> ptr2(new Test());
    ptr2->test();

    return 0;
}

带引用计数智能指针

//带引用计数智能指针
#include <iostream>
#include <memory.h>

using namespace std;

template<typename T> 
class RefCnt
{
public:
	RefCnt(T *ptr = nullptr):mptr (ptr)
	{
		if (mptr != nullptr)
			mcount = 1;
	}
	void addRef(){ mcount++; }//增加引用计数
	int delRef(){ return --mcount;}//减少引用计数
private :
	T *mptr;
	int mcount;
};

template<typename T>
class Csmartptr
{
public:
	Csmartptr(T* ptr = nullptr) :mptr(ptr) 				
	{
		mpRefCnt = new RefCnt<T>(mptr);
	}
	/*Csmartptr(const Csmartptr<T> &src)
	{
		mptr = new T(*src .mptr) ;
	}*/
	~Csmartptr() 
	{ 
		if (0 == mpRefCnt->delRef () )
		{
			delete mptr; 
			mptr = nullptr;
		}
	}
	T& operator*() { return *mptr; }
	T* operator->() {return mptr; }

	Csmartptr(const Csmartptr<T> &src):mptr(src.mptr), mpRefCnt(src.mpRefCnt)
	{
		if (mptr != nullptr)
		mpRefCnt->addRef() ;
	}

	Csmartptr<T>& operator= (const Csmartptr<T> &src)
	{
		if (this == &src)
			return *this;
		//删除原有对象指向的资源
		if (0 == mpRefCnt->delRef () )
		{
			delete mptr;
		}
		mptr = src.mptr;
		mpRefCnt = src.mpRefCnt ;
		mpRefCnt->addRef () ;
		return *this;
	}

private:
	T* mptr;//指向资源的指针
	RefCnt<T> *mpRefCnt;//指向该资源引用计数对象的指针
};


int main() {
    Csmartptr<int> ptr1 (new int) ;
    Csmartptr<int> ptr2(ptr1) ;
    Csmartptr<int> ptr3;
    ptr3 = ptr2;
    *ptr1 = 20;
    cout << *ptr2 << " " << *ptr3 << endl ;

    system("pause");
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/586715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【踩坑】mirai挂机运行经常自动退出怎么办?

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 目录 背景介绍 解决思路 实现方法 最终效果 背景介绍 就是说&#xff0c;后台运行了mcl&#xff0c;但经常莫名其妙自动会退出&#xff0c;导致每次都得手动的去服务器上重新启动mcl。而对于自己运行的需要用…

“老年养生”APP的设计与开发

摘要&#xff1a;我国人口老龄化呈上升趋势&#xff0c;老年人口比重增加。这是我国经济发展的一大挑战&#xff0c;也是老年健康产业的一大机遇。随着我国经济发展&#xff0c;越来越多的人开始关注自己的身体&#xff0c;这导致各种关于健康的网络应用层出不穷。但是经过分析…

正则表达式与通配符 -- *?在正则表达式与通配符中的区别

1、前言 最近因为工作需要写一些自动化脚本&#xff0c;里面需要用到正则表达式来匹配特定的字符串&#xff0c;于是查了一些正则表达式相关的资料。资料里面都提到&#xff1a;*匹配前面的子表达式0次或任意多次。我当时就纳闷&#xff0c;*到底是表示的是匹配的次数还是可以…

2. JVM内存模型深度剖析与优化

JVM性能调优 1. JDK的体系结构2. Java语言的跨平台特性3.JVM整体结构及内存模型3.1 内存模型3.1.1 PC寄存器&#xff08;线程私有&#xff09;3.1.2 虚拟机栈&#xff08;线程私有&#xff09;1. 局部变量表2. 操作数栈 本文是按照自己的理解进行笔记总结&#xff0c;如有不正确…

SimpleCG绘图函数(3)--绘制矩形

前面我们已经学习了点和线的绘制,本篇我们继续绘图函数学习----矩形的绘制&#xff0c;也就是长方形的绘制,并给出一个绘制楼房的例子演示矩形的应用。 所有绘制矩形相关函数如下&#xff1a; //以下矩形左上角坐标(left, top)&#xff0c;右下角坐标(right,bottom ) //以线条…

跨境电商系统开发-电商商城系统平台定制方案

随着业务的拓展&#xff0c;不少企业开始将目光转向国外市场&#xff0c;那么如何定制一套属于想自己的跨境出海电商商城方案呢&#xff1f;需要做好以下关口把关&#xff1a; 欢迎名片交流探讨开发平台流程 买家端(h5/pc/app) www.mardao.cn 账号 密码 卖家端(h5/pc)…

八、(重点)视图集ModelViewSet自定义action路由routers

上一章&#xff1a; 七、Django DRF框架GenericAPIView--搜索&排序&分页&返回值_做测试的喵酱的博客-CSDN博客 下一章&#xff1a; 九、DRF生成API文档_做测试的喵酱的博客-CSDN博客 一、视图集ModelViewSet与ReadOnlyViesSet ModelViewSet视图集 与 ReadOnly…

基于FPGA:运动目标检测(包围盒仿真工程,及一些调试问题)

目录 前言一、安装器件库二、仿真工程操作1、进入文件列表2、找到bounding_box_locate.vt&#xff0c;双击打开文件3、修改路径4、路径设置5、切换回“Hierarchy”&#xff0c;即工程界面6、运行仿真7、查看波形 重点&#xff1a;调试问题三、仿真代码1、仿真顶层文件2、绘制包…

node篇-fs模块儿

nodejs-fs模儿 异步 1. mkdir() 创建一个目录 // 1.mkdir 创建一个目录&#xff0c;回调函数的参数含义&#xff1a;err const fs require(fs); fs.mkdir(./avater,(err)>{console.log(err);if(err && err.code EEXIST){console.log(当前目录已经存在)} }) 当我…

华硕天选4R FA617原装Windows11原厂预装系统工厂模式恢复安装带 ASUSRecevory 一键还原22H2版本

华硕天选4R FA617X原装Windows11原厂预装系统工厂模式恢复安装带ASUSRecevory一键还原 文件地址&#xff1a;https://pan.baidu.com/s/1Pq09oDzmFI6hXVdf8Vqjqw?pwd3fs8 提取码:3fs8 华硕工厂恢复系统 &#xff0c;安装结束后带隐藏分区以及机器所有驱动软件 需准备一个16…

浅谈NoSQL数据库

数据库 数据库&#xff0c;又称为数据管理系统&#xff0c;是处理的数据按照一定的方式储存在一起&#xff0c;能够让多个用户共享、尽可能减小冗余度的数据集合&#xff0c;简而言之可视为电子化的文件柜——存储电子文件的处所。 数据库有&#xff1a;Oracle数据库、ACCESS数…

代码随想录算法训练营第四十五天 | 力扣 70. 爬楼梯(进阶), 322. 零钱兑换, 279.完全平方数

70. 爬楼梯&#xff08;进阶&#xff09; 题目 70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 改为&#xff1a;一步一个台阶&#xff0c;两个台阶&#xff0c;三个台阶&#xff…

【浅学 JDBC】

浅学JDBC 笔记记录 一、1. JDBC的概念2. JDBC快速入门2.1 DriverManager2.2 Connection2.3 Statement2.4 ResultSet 3. JDBC入门案例使用3.1 查询所有学生信息3.2 根据id查询学生信息&&新增学生信息&&修改学生信息&&删除学生信息 一、 1. JDBC的概念 …

中科易安8周年,与你相约联网智能门锁

中科易安与物联网技术发展同频 持续推动安防信息化建设 打造多场景应用的数智化通行解决方案 促进技术与安全精准对接 联网智能门锁技术硬核 中科易安打造集NB-IoT、Sub-1G Cat.1、Wifi、RS485和BLE 5.0 在内的六大通信技术组网方案 以“联网”赋能智能门锁 实现通行数…

C++11之atomic原子操作

atomic介绍 多线程间是通过互斥锁与条件变量来保证共享数据的同步的&#xff0c;互斥锁主要是针对过程加锁来实现对共享资源的排他性访问。很多时候&#xff0c;对共享资源的访问主要是对某一数据结构的读写操作&#xff0c;如果数据结构本身就带有排他性访问的特性&#xff0c…

chatgpt赋能python:Python中的等待:理解和优化

Python中的等待&#xff1a;理解和优化 Python是一种强大的编程语言&#xff0c;在构建各种应用程序时很常用。但是&#xff0c;随着应用程序越来越复杂&#xff0c;需要等待一些操作时&#xff0c;Python中的等待传统上会导致性能下降。在这篇文章中&#xff0c;我们将深入了…

可持续能源技术改变世界

文章目录 一、你在工作或生活中接触过可持续能源技术吗&#xff1f;可以分享下你的经历与看法。二、你认为可持续能源技术的优势和挑战有哪些&#xff1f;三、你了解过可持续能源技术的应用现状吗&#xff1f;四、对于可持续能源技术真的否改变世界这个问题你怎么看&#xff1f…

ifconfig工具与驱动交互解析(ioctl)

Linux ifconfig&#xff08;network interfaces configuring&#xff09; Linux ifconfig命令用于显示或设置网络设备。ifconfig可设置网络设备的状态&#xff0c;或是显示目前的设置。同netstat一样&#xff0c;ifconfig源码也位于net-tools中。源码位于net-tools工具包中&am…

《消息队列高手课》课程笔记(七)

如何使用异步设计提升系统性能&#xff1f; 异步设计如何提升系统性能&#xff1f; 假设我们要实现一个转账的微服务 Transfer(accountFrom, accountTo, amount)&#xff0c;这个服务有三个参数&#xff1a;分别是转出账户、转入账户和转账金额。 这个例子的实现过程中&…

chatgpt赋能python:Python中如何反转字符串:三种简单方法

Python中如何反转字符串&#xff1a;三种简单方法 当我们在处理字符串时&#xff0c;有时需要将其反向排列。在Python中&#xff0c;这可以通过以下三种简单方法实现&#xff1a; 1. 使用内置的切片方法 在Python中&#xff0c;可以使用字符串的切片方法将其反转。这种方法非…