C++ 程序设计:单例+原型(手机原型机和量产机)

这篇具有很好参考价值的文章主要介绍了C++ 程序设计:单例+原型(手机原型机和量产机)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.简介

1.1单例模式

C++单例模式被广泛应用于需要全局唯一实例的场景。以下是一些常见的使用场景:

  1. 日志记录器
    在大多数应用程序中,需要一个全局的日志记录器来记录系统运行时的事件和错误。使用单例模式可以确保只有一个日志记录器实例,并能够在整个应用程序中共享和访问。

  2. 数据库连接池
    数据库连接是有限且昂贵的资源,为了避免频繁地创建和销毁连接,可以使用单例模式来管理数据库连接池。这样可以确保在应用程序中只有一个连接池实例,并且可以在需要时轻松获取数据库连接。

  3. 配置管理器
    配置管理器负责加载和管理应用程序的配置信息,例如数据库连接字符串、日志级别等。通过单例模式,可以确保只有一个配置管理器实例,并能够在整个应用程序中统一访问配置信息。

  4. 全局对象管理器
    在某些应用程序中,可能存在需要全局访问的对象,例如全局事件管理器、全局资源管理器等。使用单例模式可以确保这些全局对象只有一个实例,并能够在整个应用程序中方便地进行访问和使用。

  5. 线程池
    线程池用于管理和调度多个线程执行任务,通过单例模式,可以确保只有一个线程池实例,并能够在整个应用程序中灵活地进行任务分发和执行。

这些只是一些常见的使用场景,实际上,单例模式可以适用于任何需要一个全局唯一实例的情况。但是,需要注意的是,单例模式可能会带来全局共享状态的问题,因此在使用单例模式时需要仔细考虑其潜在的风险和副作用。同时,还要记住,在多线程环境中使用单例模式需要考虑线程安全性。

1.2 原型模式

      原型模式是一种通过复制现有对象来创建新对象的设计模式。它使用一个原型对象作为创建对象的样板,通过克隆原型对象来生成新的对象,而不是使用传统的实例化过程。
      原型模式的核心思想是使用已有对象作为原型,通过复制(克隆)这个原型来创建新的对象,而不是通过传统的实例化方式。这种方式允许我们在运行时动态地创建对象,并且可以避免耗费时间和资源去重新初始化对象。

1.3 比喻-手机原型机和量产机

原型模式和单例模式可以这样比喻我们要制作一款手机:

  1. 原型模式比喻为手机的制作过程中,我们先制作一个原型机,并通过复制原型机来制造更多的手机。原型机是一个已经设计好的模板,我们可以根据它来制造新的手机,而每个手机都可以独立使用和修改。这样,我们可以根据原型机的特性和功能来扩展和修改手机,从而得到多个不同的手机实例。

  2. 单例模式比喻为手机的制造过程中,我们只允许制造一台手机,这台手机成为该品牌的唯一代表。无论是在什么地方,我们都只能获得并使用这一台手机。这样做的好处是,我们可以保证这台手机的唯一性,避免资源浪费,并且方便全局访问。

2.单例的简单实现

class SysParaData : 
{
public:
    static SysParaData &instance()
    {
        static SysParaData self;
        return self;
    }

private:

    SysParaData();
    ~SysParaData();
    SysParaData(const SysParaData &self);
    const SysParaData &operator=(const SysParaData &self);
};

这里用单例模式定义了一个全局只有一个的数据参数类,用来存储全局的参数。

    在类中,instance()是一个公共的静态成员函数,用于返回SysParaData类的唯一实例。这个函数通过局部静态变量self来实现,在第一次调用instance()函数时创建实例。由于局部静态变量在函数退出后仍然存在,所以每次调用instance()函数都会返回同一个实例。

   同时,构造函数、析构函数、拷贝构造函数和赋值运算符被声明为私有,这意味着不能从类的外部直接实例化、销毁、复制或赋值SysParaData对象。这样可以确保只有instance()函数可以创建和访问SysParaData类的唯一实例。

    单例模式的优点之一是可以提供全局唯一的对象访问点,方便在程序中的任何地方使用该对象。通过调用SysParaData::instance()函数,可以获得对SysParaData类的唯一实例的引用。

注意:这里没有进行多线程安全的处理。如果在多线程环境中使用该单例模式,可能需要额外的线程同步措施,以确保线程安全。例如使用互斥锁或其他线程同步机制来保护实例的创建和访问过程。

3.原型模式的简单实现

// 原型类
class SysParaModifyDataBase
{
public:
    virtual SysParaModifyDataBase *Clone() = 0;
};

//
class SysParaModifyData: public SysParaModifyDataBase
{
public:
    SysParaModifyData()

    virtual Prototype *Clone()
    {
        return new SysParaModifyData(*this);
    }
    int data = 1;
};

SysParaModifyDataBase *dataSource = new SysParaModifyData();
SysParaModifyDataBase *dataModify = dataSource ->Clone();

4.原型模式和单例模式的结合

class SysParaData :
{
private:
    static SysParaData *instance; 

public:
    /* 禁止拷贝构造函数 禁止拷贝赋值运算符的另一种写法 与上面单例代码设为私有效果一样 */
    SysParaData (const SysParaData &) = delete;
    SysParaData & operator=(const SysParaData &) = delete;

    /* 单例实例的另一种写法 */
    static SysParaData *getInstance() 
    {
        if (instance == nullptr) 
        {
            instance = new SysParaData ();
        }
        return instance;
    }

    void setName(const std::string& newName) 
    {
        name = newName;
    }

    std::string getName() const 
    {
        return name;
    }

    SysParaData *clone() const 
    {
        SysParaData *cloneInstance = new SysParaData ();
        cloneInstance->setName(this->name);
        return cloneInstance;
    }
};

如果使用clone()方法克隆一个SysParaData对象,并使用该克隆对象调用setName()修改名称,那么原始的单例对象将不受影响,它们是相互独立的。因此,克隆对象和原始单例对象不再是同一个单例。

单例模式的规则是一个类只能有一个实例,并且通过getInstance()方法获取单例实例。在这个例子中,我们使用静态变量instance来存储唯一的单例实例,而且通过禁止拷贝构造函数和拷贝赋值运算符的使用来确保只有一个实例。克隆方法clone()是为了使用已有的单例对象来创建新的对象实例。

     被克隆之后的对象如果不使用clone()方法创建,而是直接使用单例对象的指针进行赋值或传递,那么它们仍然是指向同一个单例的指针。

例如:

SysParaData *singleton = SysParaData::getInstance();
SysParaData *cloneInstance = singleton->clone();  // 克隆单例对象

SysParaData *directAssignment = singleton;        // 直接赋值
SysParaData *functionParameter = cloneInstance;   // 作为函数参数传递

// 修改单例对象的名称
singleton->setName("Singleton");

// 输出对象的名称
std::cout << "Singleton Name: " << singleton->getName() << std::endl;
std::cout << "Direct Assignment Name: " << directAssignment->getName() << std::endl;
std::cout << "Function Parameter Name: " << functionParameter->getName() << std::endl;

输出结果将会是:

Singleton Name: Singleton
Direct Assignment Name: Singleton
Function Parameter Name: Cloned Instance

可以看到,直接赋值或作为函数参数传递的对象指针仍然指向同一个单例对象,因此它们的名称相同。只有通过clone()方法创建的对象是一个独立的克隆实例,它们和原始单例对象是不同的。

因此,被克隆之后的对象,如果不使用clone()方法创建,而是直接使用单例对象的指针进行赋值或传递,仍然是指向同一个单例实例,因此仍然是单例。

5.总结

    当原型模式与单例模式结合在一起时,可以实现一个可以克隆的单例。

     在传统的单例模式中,类只能有唯一的一个实例,并且使用静态方法获取该实例。而在原型模式中,可以通过复制原型对象来创建新的对象实例。

    当将这两种模式结合在一起时,通过克隆原型对象,可以创建多个具有相同属性和行为的实例,同时保持单例的特性,即每次克隆都得到同一个实例。

    这种结合模式的应用场景是当希望在单例基础上创建新的对象实例,这些新实例保持与原始实例相同的初始状态,并且这些实例之间相互独立。

    使用这种结合模式,可以方便地创建多个独立且具有相同初始状态的对象,同时避免了在使用时传递参数的麻烦。它提供了更大的灵活性和可扩展性,同时仍然保持了单例的特性。

注意:此结合模式的实现需要对原型对象进行深度拷贝,以确保每个克隆对象是独立的。否则,如果使用浅拷贝,所有克隆对象将共享同一个状态,这不符合原型模式的预期。文章来源地址https://www.toymoban.com/news/detail-563826.html

到了这里,关于C++ 程序设计:单例+原型(手机原型机和量产机)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【高级程序设计语言C++】特殊类设计

    拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 用C++11的话,可以使用特殊的语法来实现一个不能被拷贝的类。在C++11中,可以使用删除函数(deleted function)来禁用拷

    2024年02月10日
    浏览(30)
  • C++ 程序设计入门

    ✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 程序是算法与数据结构的载体,是计算机用以

    2024年02月11日
    浏览(26)
  • FX PLC手机版程序设计仿真软件(支持软件及硬件下载在线仿真)

    简介: PLC程序设计是一款安卓/鸿蒙手机PLC梯形图编程仿真器,软件支持三菱FX PLC编程指令,支持软件及硬件(通过蓝牙现国产高FX PLC工控板及部份三菱FX PLC)程序下载及在线调试仿真,软件自带3D动画实例仿真,适合电工及自动化爱好者学习PLC编程技术。也适合电气工程人员开

    2024年04月10日
    浏览(39)
  • java毕业设计——基于java+Eclipse+jsp的网上手机销售系统设计与实现(毕业论文+程序源码)——网上手机销售系统

    大家好,今天给大家介绍基于java+Eclipse+jsp的网上手机销售系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦。需要下载开题报告PPT模板及论文答辩PPT模板等的小伙伴,可以进入我的博客主页查看左侧最下面栏目中的自助下载方法哦 文章目录: 本文所讲述的

    2024年02月09日
    浏览(39)
  • 【C++ 程序设计】第 1 章:C++ 语言简介

    目录 一、C++ 语言的发展简史 二、C++ 语言的特点 (1)基本的输入/输出 (2)头文件和命名空间 (3)强制类型转换运算符  (4)函数参数的默认值  (5)引用和函数参数的传递 ① 引用的定义 ② 引用在函数中的使用 (6)const 与指针共同使用 (7)内联函数  (8)函数的

    2024年02月07日
    浏览(78)
  • C++程序设计函数部分(定义+实例)

    目录 1、内联函数 2、默认形参值函数 3、重载函数 4、系统函数 (1)定义 在函数前面加上 inline 申明 eg: inline double CalArea(double radius) { return 3.14*radius*radius; } void main() { double r(3.0); double area; area=CalArea(r); coutareaendl; } (2)作用 提高运行的速度。 对于一些程序代码小,运行时间

    2023年04月14日
    浏览(35)
  • 【高级程序设计语言C++】初识模板

    概念: 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。 具体格式: templatetypename T1, typename T2,…,typename Tn 返回值类型 函数名(参数列表){} 输出结果: typename是用来定义模板参数,也可以使用class(切记

    2024年02月15日
    浏览(30)
  • 设计模式-创建型模式(单例、工厂、建造、原型)

    设计模式:软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。 面向对象三大特性:封装、继承、多态。 面向对象设计的SOLID原则: (1)开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情

    2024年02月08日
    浏览(43)
  • 【C++ 程序设计】实战:C++ 实践练习题(1~10)

    目录 01. 二维数组反对角线之和 02. 奇偶性  03. 指针与变量 04. 员工薪资  05. 整型值(%4d 进行格式化) 06. 求三个数中的最大值和最小值 07. 同一字母次数统计 08. 字符串回文判断 09. 闰年判断 10. 交换两个双精度数 【代码详解】 以上代码 计算的是 反对角线(从右上角到左下

    2024年02月14日
    浏览(30)
  • C++程序设计基础【五】(引用和指针)

    引用是对象的替代名称,以简化实体之间的通信。当声明一个引用变量时,不会在内存中创建一个新的对象,而只是声明一个现有变量的替代名称 引用变量在原始变量前加上r并将首字母大写,形成约定,方便查看绑定的对象 1.复合类型 引用类型是复合类型,但不能用double的

    2024年02月07日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包