Figure.cpp
#include "Figure.h"
#include <iostream>
#include <fstream>
#include <map>
#define _USE_MATH_DEFINES
#include "math.h"
#include <vector>
using std::vector;


//класс круг
Circle::Circle(Point center, int rad, int color):Figure(color),center(center),rad(rad) {}

double Circle::place() const {
#ifdef DEBUG
	std::cerr << "In Circle::place()\n";
#endif 
	return M_PI * rad * rad;
}

double Circle::perimetr() const
{
#ifdef DEBUG
	std::cerr << "In Circle::perimetr()\n";
#endif 
	return M_PI * 2 * rad;
}

Figure::Point Circle::getCenter()
{
	return center;
}

double Circle::getRad()
{
	return rad;
}

void Circle::Print(std::ostream& stream) const
{
	stream << "Color = " << getColor() << " CenterX = ";
}

void Circle::readinFile(std::ostream& stream)
{
	int x = getCenter().x;
	int y = getCenter().y;
	stream << "CIRCLE\n" << "Color = " << getColor() << "\n" << " CenterX = " << x << "\n" << " Center y" << y;
}
std::string Circle::writeinFile(std::ifstream& stream)
{
	std::string line;
	while (stream >> line) { // Считывает данные из файла построчно
		std::cout << line << std::endl; // Выводит считанные данные в консоль
	}
	return line;
}



//класс Треугольник
Triangle::Triangle(Figure::Point p1, Figure::Point p2, Figure::Point p3, int color):
	Figure(color), p1(p2), p2(p2), p3(p3) {}

double Triangle::place() const {
#ifdef DEBUG
	std::cerr << "In Triangle::place()\n";
#endif 
	double ans = 0.5 * ((p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y));
	if (ans < 0) ans = -ans;
	return ans;
}

double Triangle::perimetr() const {
#ifdef DEBUG
	std::cerr << "In Triangle::perimetr()\n";
#endif 
	double dist1 = std::sqrt(std::pow(p1.x - p2.x, 2) +std::pow(p1.y - p2.y, 2)); //рсстояние двух точек на плоскости
	double dist2 = std::sqrt(std::pow(p2.x - p3.x, 2) + std::pow(p2.y - p3.y, 2));
	double dist3 = std::sqrt(std::pow(p3.x - p1.x, 2) + std::pow(p3.y - p1.y, 2));
	return dist1 + dist2 + dist3;
}

Figure::Point Triangle::getP1() const { return p1; }
Figure::Point Triangle::getP2() const { return p2; }
Figure::Point Triangle::getP3() const { return p3; }

void Triangle::readinFile(std::ostream& stream)
{
	stream << "TRIANGLE\n" << "Color = " << getColor() << "Point1x = " << getP1().x << "Point1y = " << getP1().y;
}

std::string Triangle::writeinFile(std::ifstream& stream)
{
	return std::string();
}

void Triangle::Print(std::ostream& stream) const
{
	stream << "Color = " << getColor() << "Point1x = " << getP1().x << "Point1y = " << getP1().y;
}


//класс Полигон
Polygon::Polygon(vector<Point> points, int numPoints, int color) : 
	Figure(color), points(points), numPoints(numPoints) {}

double Polygon::place() const {
#ifdef DEBUG
	std::cerr << "In Polygon::place()\n";
#endif 
	double area = 0.0;
	int n = points.size();
	for (int i = 0; i < n; i++)
	{
		int j = (i + 1) % n;
		area += (points[i].x + points[j].x) * (points[i].y - points[j].y);
	}
	area /= 2.0;
	return std::abs(area);
}

double Polygon::perimetr() const {
#ifdef DEBUG
	std::cerr << "In Polygon::perimetr()\n";
#endif 
	double perimeter = 0.0;
	for (int i = 0; i < numPoints; i++)
	{
		int j = (i + 1) % numPoints;
		double dist = std::sqrt(std::pow(points[i].x - points[j].x, 2) + std::pow(points[i].y - points[j].y, 2));
		perimeter += dist;
	}
	return perimeter;
}

vector<Figure::Point> Polygon::getPoints() const
{
	return points;
}

int Polygon::getSize() const
{
	return numPoints;
}

void Polygon::Print(std::ostream& stream) const
{
	stream << "Size = " << getSize();
}

void Polygon::readinFile(std::ostream& stream)
{
	stream << "Size = " << getSize();
}
std::string Polygon::writeinFile(std::ifstream& stream)
{
	std::string line;
	while (stream >> line) { // Считывает данные из файла построчно
		std::cout << line << std::endl; // Выводит считанные данные в консоль
	}
	return line;
}

Fugure.h
#pragma once
#include <iostream>
#include <vector>
#include <map>
#include "singleton.h"
using std::vector;

	class Figure
	{
	protected:
		int color;
		virtual void Print(std::ostream& stream) const = 0;
		friend std::ostream& operator<<(std::ostream& stream, const Figure& f)
		{
			f.Print(stream);
			return stream;
		}
	public:
		Figure(int color) : color(color) {};
		virtual double place() const = 0;
		virtual double perimetr() const = 0;
		struct Point
		{
			int x, y;
			Point(int x, int y) : x(x), y(y) {};
		};
		virtual std::string writeinFile(std::ifstream& stream) = 0; //
	};

	class Circle : public Figure {
		Point center;
		int rad;
	public:
		Circle(Point center, int rad, int color);
		virtual double place() const;
		virtual double perimetr() const;
		Point getCenter();
		double getRad();
		int getColor() const
		{
			return color;
		}
		void readinFile(std::ostream& stream); //
		std::string writeinFile(std::ifstream& stream) override; //
	protected:
		void Print(std::ostream& stream) const;
	};

	class Triangle : public Figure {
		Point p1, p2, p3;
	public:
		Triangle(Point p1, Point p2, Point p3, int color);
		virtual double place() const;
		virtual double perimetr() const;
		Point getP1() const;
		Point getP2() const;
		Point getP3() const;
		int getColor() const
		{
			return color;
		}
		void readinFile(std::ostream& stream); //
		virtual std::string writeinFile(std::ifstream& stream)  override; //
	protected:
		void Print(std::ostream& stream) const;
	};

	class Polygon : public Figure {
		vector<Point> points;
		int numPoints;
	public:
		Polygon(vector<Point> points, int numPoints, int color);
		virtual double place() const;
		virtual double perimetr() const;
		vector<Point> getPoints() const;
		int getSize() const;
		void readinFile(std::ostream& stream); //
		virtual std::string writeinFile(std::ifstream& stream)  override; //
	protected:
		void Print(std::ostream& stream) const;

	};
singleton.h 
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <string>
#include <map> 



template <class T>
class Singleton {
public:
	static T& instance() {

	       if (myInstance == 0)  {
			myInstance = new T;
			}
		

		return *myInstance;
	}
	static void terminate() {
		if (myInstance != 0) {
			delete myInstance; 
			//myInstance = 0;
		}
	}
protected:
	static T* myInstance;
	Singleton() {}
	Singleton(const Singleton&) {}
	Singleton& operator=(const Singleton&) { return *this; }
	//
	static std::map <std::string, T*> instances; //static

	
};
template <class T>
T* Singleton<T>::myInstance = 0;
#endif
#pragma once

FiguresFactory.h 
#pragma once
#include "singleton.h"
#include "Figure.h"
#include "string"

class FiguresFactory :public Singleton<FiguresFactory>
{
	public:
		typedef Figure* (*CreateFigureCallback)();
	private:
		typedef std::map<int, CreateFigureCallback> CallbackMap;
		CallbackMap callbacks;
	public:
		bool RegisterFigure(int FigureID, CreateFigureCallback CreateFN)
		{
			return callbacks.insert(CallbackMap::value_type(FigureID, CreateFN)).second;
		}
		
		bool UnregisterFigure(int FigureID);
		
		Figure* CreateFigure(int FigureID)   //Figure* CreateFigure(int FigureID)
		{
			CallbackMap::const_iterator i = callbacks.find(FigureID);
			if (i == callbacks.end()) {
				throw std::runtime_error("Unknown typeID");
			}
			return (i->second)(); //добавить параметры? return (i->second)();
		}
		
		friend class Singleton<FiguresFactory>;

		Figure* CreateFigureFromFile(std::string str);
	};
FiguresFactory.cpp
#include "FiguresFactory.h"
#include "Figure.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>

bool FiguresFactory::UnregisterFigure(int FigureID) {
	return callbacks.erase(FigureID) == 1;
}

namespace
{
	
	Figure* CreateTriangle() {
		//создаём фигуру со слуцчайным параметров
		return new Triangle(Figure::Point(rand() % 100, rand() % 100),
			Figure::Point(rand() % 100, rand() % 100),
			Figure::Point(rand() % 100, rand() % 100), rand() % 100); 

	}

	const int TRIANGLE = 1; //идентификатор типа
	//регистрируем нвоы тип фигуры
	const bool triangleRegistered = FiguresFactory::instance().RegisterFigure(TRIANGLE, CreateTriangle);


	Figure* CreatePolygon() {
		int n = rand() % 100;
		vector<Figure::Point> points;
		for (int j = 0; j < n; j++)
		{
			points.push_back(Figure::Point(rand() % 100, rand() % 100));
		}
		return new Polygon(points, n, rand() % 100);
	}
	const int POLYGON = 2;
	const bool polygonRegistered = FiguresFactory::instance().RegisterFigure(POLYGON, CreatePolygon);
	

	поомги доабитьв  каждый клас фигуры функцию записи в тестовый файл. Функции долэен передаваться один парметр-ссылка на объект ofstream (прив ызове функции предполагается что файл уже открыт длдя записи. Функция вначале записывает в файл идентификатор типа, а затм все его параметры.
) Потом в каждый клас фигуры функцию чтения из тектового файл. Один параметр- ссылка на объкт ifstream