C++设计模式::享元模式(combination)-可运行

news2024/11/15 13:27:37

实现:
    1) cShape:抽象接口;
       cShape*:具体实现的接口;
    
    2) cFactory:按照传入参数color来区别对象, 如果已经创建过, 那就返回已有的, 否则创建新的.

使用:
    传入参数, 获取被创建的对象(创建尽可能少的对象)

1) 设计框架

        /*shape.hpp*/
#pragma once
#ifndef __SHAPE_HPP
#define __SHAPE_HPP
#include <string>

namespace __flyweight{

class cShape{
public:
  virtual ~cShape();
public:
  void setColor(std::string const &color);
  void setX(int x);
  void setY(int y);
public:
  virtual void draw() = 0;
  virtual void setRadius(int radius);
  virtual void setWidth(int width);
  virtual void setHeight(int height);
protected:
  cShape(std::string const&color, int x, int y);
  std::string _M_color;
  int _M_x;
  int _M_y;
};

}
#include "shape_circle.hpp"
#include "shape_rectangle.hpp"
#include "shape_square.hpp"

#endif

        /*shape_circle.hpp*/
#pragma once
#ifndef __SHAPE_CIRCLE_HPP
#define __SHAPE_CIRCLE_HPP
#include "shape.hpp"

namespace __flyweight{

class cCircle:virtual public cShape{
public:
  cCircle(std::string const &color, int x = 0, int y = 0, int radius = 0);
public:
  void draw() override;
  void setRadius(int radius) override;
private:
  int _M_radius;
};

}

#endif

        /*shape_rectangle.hpp*/
#pragma once
#ifndef __SHAPE_RECTANGLE__HPP
#define __SHAPE_RECTANGLE__HPP
#include "shape.hpp"

namespace __flyweight{

class cRectangle:virtual public cShape{
public:
  cRectangle(std::string const &color, int x = 0, int y = 0, int width = 0, int height = 0);
public:
  void draw() override;
  void setWidth(int width) override;
  void setHeight(int height) override;
private:
  int _M_width;
  int _M_height;
};

}

#endif

        /*shape_square.hpp*/
#pragma once
#ifndef __SHAPE_SQUARE_HPP
#define __SHAPE_SQUARE_HPP
#include "shape.hpp"

namespace __flyweight{

class cSquare:virtual public cShape{
public:
  cSquare(std::string const &color, int x = 0, int y = 0, int width = 0);
public:
  void draw() override;
  void setWidth(int width) override;
private:
  int _M_width;
};

}

#endif

        /*factory.hpp*/
#ifndef __FLYWEIGHT__HPP
#define __FLYWEIGHT__HPP
#include "shape.hpp"
#include <string>
#include <map>

namespace __flyweight{

class cFactory{
public:
  ~cFactory();
public:
  cShape *getCircle(std::string const &color);
  cShape *getRectangle(std::string const &color);
  cShape *getSquare(std::string const&color);
private:
  std::map<std::string /*color*/, cShape*> _M_circles;
  std::map<std::string /*color*/, cShape*> _M_rectangles;
  std::map<std::string /*color*/, cShape*> _M_squares;
};

}


#endif

2) 实现框架

        /*shape.cpp*/
#include "shape.hpp"
#include <stdio.h>
#include <string.h>
#include <ctype.h>

namespace __flyweight{

cShape::~cShape(){
}

cShape::cShape(std::string const&color, int x, int y)
:_M_color(color), _M_x(x), _M_y(y)
{

}
void cShape::setColor(std::string const &color){
  _M_color = color;
}
void cShape::setX(int x){
  _M_x = x;
}
void cShape::setY(int y){
  _M_y = y;
}

void cShape::setRadius(int radius){
}
void cShape::setWidth(int width){
}
void cShape::setHeight(int height){
}

}

        /*shape_circle.cpp*/
#include "shape_circle.hpp"
#include <stdio.h>

namespace __flyweight{

cCircle::cCircle(std::string const &color, int x, int y, int radius)
:cShape(color, x, y)
{
  setRadius(radius);
}
void cCircle::setRadius(int radius)
{
  _M_radius = radius; 
}
void cCircle::draw()
{
  printf("cCircle::color(%s),x(%d),y(%d),radius(%d)\n", _M_color.c_str(), _M_x, _M_y, _M_radius );
}

}

        /*shape_rectangle.cpp*/
#include "shape_rectangle.hpp"
#include <stdio.h>

namespace __flyweight{

cRectangle::cRectangle(std::string const &color, int x, int y, int width, int height)
:cShape(color, x, y)
{
  setWidth(width);
  setHeight(height);
}
void cRectangle::setWidth(int width)
{
  _M_width = width; 
}
void cRectangle::setHeight(int height)
{
  _M_height = height; 
}
void cRectangle::draw()
{
  printf("cRectangle::color(%s),x(%d),y(%d),width(%d),height(%d)\n", _M_color.c_str(), _M_x, _M_y, _M_width, _M_height );
}

}

        /*shape_square.cpp*/
#include "shape_square.hpp"
#include <stdio.h>

namespace __flyweight{

cSquare::cSquare(std::string const &color, int x, int y, int width)
:cShape(color, x, y)
{
  setWidth(width);
}
void cSquare::setWidth(int width)
{
  _M_width = width; 
}
void cSquare::draw()
{
  printf("cSquare::color(%s),x(%d),y(%d),width(%d)\n", _M_color.c_str(), _M_x, _M_y, _M_width);
}

}


        /*factory.cpp*/
#include "factory.hpp"
#include <stdio.h>

namespace __flyweight{

cFactory::~cFactory()
{
  while( !_M_circles.empty() )
  {
    auto it = _M_circles.begin();
    delete it->second, it->second = nullptr;
    _M_circles.erase( it );
  }
  while( !_M_rectangles.empty() )
  {
    auto it = _M_rectangles.begin();
    delete it->second, it->second = nullptr;
    _M_rectangles.erase( it );
  }
  while( !_M_squares.empty() )
  {
    auto it = _M_squares.begin();
    delete it->second, it->second = nullptr;
    _M_squares.erase( it );
  }
}

cShape *cFactory::getCircle(std::string const &color)
{
  cShape *ret = nullptr;

  auto it = _M_circles.find(color);
  if( it == _M_circles.end() )
  {
    if( (ret = new cCircle(color) ) )
    {
      _M_circles.insert(std::make_pair(color, ret));
    }
  }
  else
  {
    ret = it->second;
  }

  return ret;
}
cShape *cFactory::getRectangle(std::string const &color)
{
  cShape *ret = nullptr;

  auto it = _M_rectangles.find(color);
  if( it == _M_rectangles.end() )
  {
    if( (ret = new cRectangle(color) ) )
    {
      _M_rectangles.insert(std::make_pair(color, ret));
    }
  }
  else
  {
    ret = it->second;
  }

  return ret;
}
cShape *cFactory::getSquare(std::string const &color)
{
  cShape *ret = nullptr;

  auto it = _M_squares.find(color);
  if( it == _M_squares.end() )
  {
    if( (ret = new cSquare(color) ) )
    {
      _M_squares.insert(std::make_pair(color, ret));
    }
  }
  else
  {
    ret = it->second;
  }

  return ret;
}

}

3) 用户调用

#include "factory.hpp"
#include <cstdlib>
#include <cstdio>
#include <time.h>

static char const *sg_colors[]={
"Red", "Green", "Blue", "White", "Black"
};
#define COLOR_SIZE (sizeof(sg_colors)/sizeof(sg_colors[0]))

std::string getRandomColor()
{
  return sg_colors[ abs(rand())%COLOR_SIZE ];
}
int getRandomX()
{
  return rand();
}
int getRandomY()
{
  return rand();
}
int getRandomRadius()
{
  return rand();
}
int getRandomWidth()
{
  return rand();
}
int getRandomHeight()
{
  return rand();
}

int main(int argc, char *argv[])
{
  if( argc != (1 + 1)){
    fprintf(stderr, "Usage:%s <object-count>\n", argv[0]);
    return EXIT_FAILURE;
  }

  long long OBJ_SIZE = atoll(argv[1]);
  time(nullptr);
  __flyweight::cFactory shapeFactory;
  {
  printf("---------------------------------\n");
     __flyweight::cShape * circle = nullptr;
    for(int iobj = 0; iobj < OBJ_SIZE; iobj++ )
    {
      circle = shapeFactory.getCircle( getRandomColor() );
      circle->setX( getRandomX() );
      circle->setY( getRandomY() );
      circle->setRadius( getRandomRadius() );

      circle->draw();
    }
  }
  {
  printf("---------------------------------\n");
     __flyweight::cShape * rectangle = nullptr;
    for(int iobj = 0; iobj < OBJ_SIZE; iobj++ )
    {
      rectangle = shapeFactory.getRectangle( getRandomColor() );
      rectangle->setX( getRandomX() );
      rectangle->setY( getRandomY() );
      rectangle->setWidth( getRandomWidth() );
      rectangle->setHeight( getRandomHeight() );

      rectangle->draw();
    }
  }
  {
  printf("---------------------------------\n");
     __flyweight::cShape * square = nullptr;
    for(int iobj = 0; iobj < OBJ_SIZE; iobj++ )
    {
      square = shapeFactory.getSquare( getRandomColor() );
      square->setX( getRandomX() );
      square->setY( getRandomY() );
      square->setWidth( getRandomWidth() );

      square->draw();
    }
  }
  return EXIT_SUCCESS;
}

4) 编译与运行

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

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

相关文章

CSS伪元素详解以及伪元素与伪类的区别

伪元素常常被误解为伪类&#xff0c;主要在于他们的语法相似&#xff0c;都是对于选择器功能的扩展&#xff0c;相似程度很高导致被混淆。 本文通过详细介绍伪元素和常见的使用方法&#xff0c;最后也会分析下伪元素与伪类的基本区别。 基本描述 CSS伪元素也是应用于选择器的…

渗透测试:Linux提权精讲(一)之sudo方法第一期

目录 写在开头 CVE-2019-14287 sudo apt和sudo apt-get sudo apache2 sudo ash sudo awk sudo base32/58/64/nc/z sudo cp sudo cpulimit sudo curl sudo date sudo dd sudo dstat sudo ed sudo env sudo exiftools 总结与思考 写在开头 在进行渗透测试获取…

sql server表值函数

一、创建测试表 Employees 二、创建表值函数 -- DROP FUNCTION TableIntSplit;CREATE FUNCTION TableIntSplit(Text NVARCHAR(4000),Sign NVARCHAR(4000)) RETURNS tempTable TABLE(Id INT ) AS BEGIN DECLARE StartIndex INT DECLARE FindIndex INT DECLARE Content VARCHAR(…

浅谈 Spring AOP 思想

Spring AOP AOP 切面编程普通代理类JDK动态代理Cglib动态代理AOPAOP术语AOP切面编程的优势Advice通知类型&#xff08;5种&#xff09;通知的执行顺序 Order切入点表达式表达式execution注解annotation Spring事务管理Transactional 及 Transactional 的两个属性Transactional …

AR开发平台 | 探索AR技术在建筑设计中的创新应用与挑战

随着AR技术的不断发展和普及&#xff0c;越来越多的建筑师开始探索AR技术在建筑设计中的应用。AR(增强现实)技术可以通过将虚拟信息叠加到现实场景中&#xff0c;为设计师提供更加直观、真实的建筑可视化效果&#xff0c;同时也可以为用户带来更加沉浸式的体验。 AR开发平台广…

SpringBoot项目连接数据库

1、找到applications.yml&#xff0c;如下图 2、写入代码 server:port: 9494spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/自己的数据库表名?serverTimezoneGMT%2b8username: rootpassword: root

短视频矩阵源码开发搭建分享--多账号授权管理

目录 文章目录 前言 一、矩阵号系统是什么&#xff1f; 二、使用步骤 1.创建推广项目 2.多账号授权 3.企业号智能客服系统 总结 前言 短视频多账号矩阵系统&#xff0c;通过多账号一键授权管理的方式&#xff0c;为运营人员打造功能强大及全面的“矩阵式“管理平台。…

修改整数(有点坑,所以发出来了)

问题描述 小贝给了小聪一个正整数 x&#xff0c;但是小聪决定把这个数改掉。她可以把整数 x 每个位置上的数 t 改成 9-t。 请你帮助小聪来计算一下&#xff0c;如何把 x 改成一个最小的正整数&#xff0c;注意&#xff0c;不能出现首位为 0 的情况。 输入格式 输入一个正整数…

Vue通过指令 命令将打包好的dist静态文件上传到腾讯云存储桶 (保存原有存储目录结构)

1、在项目根目录创建uploadToCOS.js文件 (建议起简单的名字 方便以后上传输入命令方便) 2、uploadToCOS.js文件代码编写 const path = require(path); const fs = require(fs); const COS = require(cos-nodejs-sdk-v5);// 配置腾讯云COS参数 const cos = new COS({SecretI…

NoSQL-Redis集群

NoSQL-Redis集群 一、集群&#xff1a;1.单点Redis带来的问题&#xff1a;2.解决&#xff1a;3.集群的介绍&#xff1a;4.集群的优势&#xff1a;5.集群的实现方式&#xff1a; 二、集群的模式&#xff1a;1.类型&#xff1a;2.主从复制&#xff1a; 三、搭建主从复制&#xff…

vscode 打开文件时如何在资源管理器中展开文件所在的整个目录树(包含node_modules)

如题。去 首选项 --> 设置 中 搜索 “Auto Reveal”&#xff0c;然后选true&#xff0c;注意把下面的Auto Reveal Exclude排除项中的node_modules去掉&#xff0c;这样才能定位到node_modules中的文件。 **/node_modules

【FPGA IP系列】FIFO的通俗理解

FPGA厂商提供了丰富的IP核&#xff0c;基础性IP核都是可以直接免费调用的&#xff0c;比如FIFO、RAM等等。 本文主要介绍FIFO的一些基础知识&#xff0c;帮助大家能够理解FIFO的基础概念。 一、FIFO介绍 FIFO全称是First In First Out&#xff0c;即先进先出。 FIFO是一个数…

函数重载与引用

文章目录 一、函数重载1. 重载规则2.重载列子3.函数名修饰规则 二、引用1.本质2.特性1. 引用必须在定义时初始化2 . 一个变量可以有多个引用3 . 引用一旦引用一个实体&#xff0c;就不能引用其他实体 3.引用例子4.引用的权限5.效率比较6.指针跟引用的区别 一、函数重载 函数重…

我的创作纪念日 --- 鲁迅文学无聊版

机缘 ------从第一次使用CSDN这个网站到现在已经快四年了&#xff0c;我大抵是病了&#xff0c;2021年7月29日才心血来潮写下来了第一篇自己的博客&#xff0c;回顾起来&#xff0c;已经过去了2年。如此这般&#xff0c;断断续续的写过一些博客&#xff0c;但终归是心血来潮罢了…

【Docker】Docker的优势、与虚拟机技术的区别、三个重要概念和架构及工作原理详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 作者简介&#xff1a; 辭七七&#xf…

PS - Photoshop 实现涂抹功能 (橡皮擦、图章、吸管、画笔)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131997323 在 Photoshop 中&#xff0c;橡皮擦工具&#xff0c;以及吸管工具和画笔工具可以配合使用&#xff0c;实现涂抹功能&#xff0c;再通过…

第四届世界蜂疗大会在中国·重庆武隆盛大开幕

【39蜂疗网】记者 讯 7月25日至27日&#xff0c;“世界中联蜂疗专业委员会第五届学术年会暨第四届世界蜂疗大会、中国民族医药学会蜂疗分会2023年学术年会”在重庆武隆正式启幕。开幕式上&#xff0c;重庆市政府副市长但彦铮宣布开幕&#xff1b;人民英雄、中国工程院院士张伯礼…

QPainter绘制雷达界面

文章目录 功能实现定义的结构体定义的函数效果图gitee源码链接 功能实现 相较于上一版&#xff0c;这一版添加的功能有&#xff1a; 1、自适应窗口 2、扫描方式&#xff08;圆周扫描、扇形扫描&#xff08;指定起始角度和结束角度&#xff09;&#xff09; 3、扫描方向&#x…

WITH AS 的 sql语法是啥意思

WITH t1 AS ( select * from my_table_1 where age >30 ), t2 AS ( select * from my_table_2 where sex M ) select * from t1 inner join t2 on t1.id t2.t_id;WITH AS 的 sql语法是啥意思&#xff1f; WITH和AS是SQL语句中的关键字&#xff0c;用于创建临时命名的查询…

hcip——路由策略

要求&#xff1a; 基础配置 AR1 [R1]int g 0/0/0 [R1-GigabitEthernet0/0/0]ip add 12.0.0.1 24[R1-GigabitEthernet0/0/0]int g 0/0/1 [R1-GigabitEthernet0/0/1]ip add 14.0.0.1 24[R1]int loop0 [R1-LoopBack0]ip add 1.1.1.1 24[R1]rip 1 [R1-rip-1]vers 2 [R1-rip-1]net…