实现:
     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;
};
}
#endif2) 实现框架
        /*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) 编译与运行


















