Множественная композиция по значению 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Множественная композиция по значению



 

Кратность дочерних объектов может быть множественной. В таком случае используются массивы дочерних объектов. Если количество объектов заранее известно, массив фиксированного размера размещается непосредственно в родительском объекте. Чаще количество объектов заранее неизвестно и определяется во время выполнения. При этом количество передается в конструкторе, который выделяет динамический блок памяти для хранения желаемого количества дочерних объектов, а в родительском объекте сохраняется указатель на начало блока. Разумеется, родительский объект становится ответственным за уничтожение выделенного блока памяти, что следует в явном виде реализовать в деструкторе. Таким действиям в родительском классе обычно сопутствуют определения конструкторов копий и перемещения, а также соответствующих операторов присвоения и перемещения.

 

Ниже представлен класс для многоугольника, состоящий из множества точек (в показанном примере, из 4 точек конкретно):

 

 

polygon.hpp

 

#ifndef _POLYGON_HPP_

#define _POLYGON_HPP_

 

//************************************************************************

 

#include " point3d.hpp"

 

//************************************************************************

 

class Polygon

{

 

/*-----------------------------------------------------------------*/

 

public:

 

/*-----------------------------------------------------------------*/

 

// Конструктор — принимает количество точек

Polygon (int _nPoints);

 

// Конструктор копий

Polygon (const Polygon & _p);

 

// Конструктор перемещения

Polygon (Polygon && _p);

 

// Деструктор

~Polygon ();

 

// Оператор присвоения

Polygon & operator = (const Polygon & _p);

 

// Оператор перемещения

Polygon & operator = (Polygon && _p);

 

// Метод доступа к количеству точек

int getNPoints () const;

 

// Методы доступа к точке по индексу

const Point3D & getPoint (int index) const;

Point3D & getPoint (int _index);

 

// Метод вычисления длины сторон многоугольника

double getPerimeter () const;

 

/*-----------------------------------------------------------------*/

 

private:

 

/*-----------------------------------------------------------------*/

 

// Начала блока хранения точек

Point3D * m_points;

 

// Количество точек

int m_nPoints;

 

/*-----------------------------------------------------------------*/

 

};

 

//************************************************************************

 

// Реализация метода доступа к количеству точек

inline int Polygon::getNPoints () const

{

return m_nPoints;

}

 

//************************************************************************

 

#endif // _POLYGON_HPP_

 

 

polygon.cpp

 

#include "polygon.hpp"

 

#include <stdexcept>

 

//************************************************************************

 

// Реализация конструктора

Polygon::Polygon (int _nPoints)

: m_nPoints(_nPoints) // Запоминаем количество точек

{

// Проверяем инвариант - как минимум 3 точки!
if (_nPoints < 3)

throw std::logic_error("Expecting at least 3 points in polygon");

 

// Выделяем блок для хранения точек и запоминаем адрес
// его начала в объекте-многоугольнике

m_points = new Point3D[ m_nPoints ];

}

 

//************************************************************************

 

// Реализация конструктора копий

Polygon::Polygon (const Polygon & _p)

{

// Извлекаем количество точек из объекта-оригинала

m_nPoints = _p.m_nPoints;

 

// Выделяем блок для хранения точек и
// запоминаем адрес его начала в объекте-многоугольнике

m_points = new Point3D[ m_nPoints ];

 

// Копируем координаты точек

for (int i = 0; i < m_nPoints; i++)

m_points[ i ] = _p.m_points[ i ];

}

 

//************************************************************************

 

// Реализация конструктора перемещения

Polygon::Polygon (Polygon && _p)

{

// Извлекаем количество точек из объекта-оригинала

m_nPoints = _p.m_nPoints;

 

// "Отбираем" у объекта-оригинала блок данных

m_points = _p.m_points;

_p.m_points = nullptr;

}

 

//************************************************************************

 

// Реализация деструктора

Polygon::~Polygon ()

{

// Освобождаем блок для хранения точек

delete[] m_points;

}

 

//************************************************************************

 

// Реализация оператора присвоения

Polygon & Polygon:: operator = (Polygon const & _p)

{

// Защита от присвоения самому себе

if (this == & _p)

return * this;

 

// Освобождаем предыдущий блок с точками

delete [] m_points;

 

// Извлекаем количество точек из объекта в правой части присвоения

m_nPoints = _p.m_nPoints;

 

// Выделяем блок для хранения точек и запоминаем адрес его начала
// в объекте-многоугольнике

m_points = new Point3D[ m_nPoints ];

 

// Копируем координаты точек

for (int i = 0; i < m_nPoints; i++)

m_points[ i ] = _p.m_points[ i ];

 

// Возвращаем ссылку на себя

return * this;

}

 

//************************************************************************

 

// Реализация оператора перемещения

Polygon & Polygon:: operator = (Polygon && _p)

{

// Защита от перемещения в самого себя

if (this == & _p)

return * this;

 

// Осуществляем обмен переменными

std::swap(m_nPoints, _p.m_nPoints);

std::swap(m_points, _p.m_points);

 

// Возвращаем ссылку на себя

return * this;

}

 

//************************************************************************

 

// Реализация метода доступа к точке по индексу без права на запись

const Point3D & Polygon::getPoint (int _index) const

{

if (_index >= 0 && _index < getNPoints())

return m_points[ _index ];

Else

throw std::logic_error("Point index is out of range");

}

 

//************************************************************************

 

// Реализация метода доступа к точке по индексу c правом на запись

Point3D & Polygon::getPoint (int _index)

{

if (_index >= 0 && _index < getNPoints())

return m_points[ _index ];

Else

throw std::logic_error("Point index is out of range");

}

 

//************************************************************************

 

// Реализация метода вычисления длины сторон многоугольника

double Polygon::getPerimeter () const

{

// Суммируем расстояния между соседними точками многоугольника

double total = 0.0;

for (int i = 0; i < m_nPoints - 1; i++)

total += m_points[ i ].distanceTo(m_points[ i + 1 ]);

return total;

}

 

//************************************************************************

 



Поделиться:


Последнее изменение этой страницы: 2017-02-17; просмотров: 166; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.131.178 (0.1 с.)