Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП_ Лекция №09 - Композиция объектов.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
754 Кб
Скачать
☆

Простейшая композиция по значению

Ниже представлен класс для точки в 3-х мерном пространстве:

point3d.hpp

#ifndef _POINT3D_HPP_

#define _POINT3D_HPP_

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

class Point3D

{

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

public:

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

// Конструктор по умолчанию – задает начало координат

Point3D ();

// Конструктор с аргументами — задает конкретные значения координат

Point3D ( double _x, double _y, double _z );

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

double getX () const;

double getY () const;

double getZ () const;

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

double distanceTo ( Point3D _p ) const;

// Перегруженные операторы сравнения на равенство и неравенство

bool operator == ( Point3D _p ) const;

bool operator != ( Point3D _p ) const;

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

private:

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

// Координаты точки по каждой из осей

double m_x, m_y, m_z;

};

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

// Метод доступа к координате по оси абсцисс

inline double Point3D::getX () const

{

return m_x;

}

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

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

inline double Point3D::getY () const

{

return m_y;

}

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

// Метод доступа к координате по оси аппликат

inline double Point3D::getZ () const

{

return m_z;

}

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

#endif // _POINT3D_HPP

point3d.cpp

#include "point3d.hpp"

#include <cmath>

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

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

Point3D::Point3D ()

: m_x( 0.0 ), m_y( 0.0 ), m_z( 0.0 )

{

}

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

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

Point3D::Point3D ( double _x, double _y, double _z )

: m_x( _x ), m_y( _y ), m_z( _z )

{

}

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

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

double Point3D::distanceTo ( Point3D _p ) const

{

double xDiff = _p.getX() - getX();

double yDiff = _p.getY() - getY();

double zDiff = _p.getZ() - getZ();

return sqrt( xDiff * xDiff + yDiff * yDiff + zDiff * zDiff );

}

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

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

bool Point3D::operator == ( Point3D _p ) const

{

return getX() == _p.getX() &&

getY() == _p.getY() &&

getZ() == _p.getZ();

}

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

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

bool Point3D::operator != ( Point3D _p ) const

{

return !( * this == _p );

}

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

Класс для окружности использует реализованный выше класс для точки для дочернего объекта, означающего координаты центра. Точка хранится в окружности по значению и не может быть отделена от окружности:

circle.hpp

#ifndef _CIRCLE_HPP_

#define _CIRCLE_HPP_

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

#include "point3d.hpp"

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

class Circle

{

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

public:

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

// Конструктор

Circle ( Point3D _center, double _radius );

// Метод доступа к координатам центра

Point3D getCenter () const;

// Метод доступа к радиусу

double getRadius () const;

// Метод вычисления длины окружности

double getPerimeter () const;

// Метод вычисления площади окружности

double getArea () const;

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

Point3D getPointOn ( double _angle ) const;

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

private:

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

// Центр окружности — дочерний объект класса Point3D

Point3D m_center;

// Радиус окружности

double m_radius;

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

};

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

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

inline Point3D

Circle::getCenter () const

{

return m_center;

}

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

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

inline double

Circle::getRadius () const

{

return m_radius;

}

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

#endif // _CIRCLE_HPP_

circle.cpp

#include "circle.hpp"

#define _USE_MATH_DEFINES // <- необходимо для работы с константой M_PI

#include <cmath>

#include <stdexcept>

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

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

Circle::Circle ( Point3D _center, double _radius )

: m_center( _center ) // <= вызов конструктора копий Point3D

, m_radius( _radius )

{

// Инвариант: радиус должен быть положительным

if ( m_radius <= 0.0 )

throw std::logic_error( "Circle radius must be positive" );

}

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

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

double Circle::getPerimeter () const

{

return 2.0 * M_PI * m_radius;

}

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

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

double Circle::getArea () const

{

return M_PI * m_radius * m_radius;

}

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

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

Point3D Circle::getPointOn ( double _angle ) const

{

// Вычисляем длины катетов по гипотенузе (радиусу) и углу

double xOffset = m_radius * cos( _angle );

double yOffset = m_radius * sin( _angle );

// Создаем новый объект-точку

return Point3D( m_center.getX() + xOffset,

m_center.getY() + yOffset,

m_center.getZ()

);

}

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

В свою очередь, класс-цилиндр использует в качестве дочернего объекта окружности для моделирования основания. Аналогично предыдущему случаю, дочерний объект-окружность хранится в объекте-цилиндре по значению. А значит внутри объекта-цилиндра есть и объект-точка, представляющая собой центр окружности-основания:

cylinder.hpp

#ifndef _CYLINDER_HPP_

#define _CYLINDER_HPP_

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

#include "circle.hpp"

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

class Cylinder

{

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

public:

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

// Конструктор. Передаем основание по ссылке.

// Передача основания по значению также допустима.

Cylinder ( Circle _base, double _height );

// Метод доступа к объекту-основанию

Circle getBase () const;

// Метод доступа к высоте цилиндра

double getHeight () const;

// Метод вычисления объема цилиндра

double getVolume () const;

// Метод вычисления площади поверхности сторон

double getSideSurfaceArea () const;

// Метод вычисления всей площади поверхности

double getFullSurfaceArea () const;

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

// и на заданной высоте

Point3D getPointOnSurface ( double _angle, double _height ) const;

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

private:

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

// Основание цилиндра — дочерний объект класса Circle

Circle m_base;

// Высота цилиндра

double m_height;

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

};

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

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

inline Circle

Cylinder::getBase () const

{

return m_base;

}

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

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

inline double

Cylinder::getHeight () const

{

return m_height;

}

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

#endif // _CYLINDER_HPP_

cylinder.cpp

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

#include "cylinder.hpp"

#include <cmath>

#include <stdexcept>

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

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

Cylinder::Cylinder ( const Circle & _base, double _height )

: m_base( _base ) // <= вызов конструктора копий класса Circle

, m_height( _height )

{

// Инвариант: высота должна быть положительной

if ( m_height <= 0.0 )

throw std::logic_error( "Cylinder height must be positive" );

}

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

// Реализация метода вычисления объема

double Cylinder::getVolume () const

{

return m_base.getArea() * m_height;

}

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

// Реализация метода вычисления площади поверхности сторон

double Cylinder::getSideSurfaceArea () const

{

return m_base.getPerimeter() * m_height;

}

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

// Реализация метода вычисления площади полной поверхности

double Cylinder::getFullSurfaceArea () const

{

return getSideSurfaceArea() + 2.0 * m_base.getArea();

}

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

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

Point3D Cylinder::getPointOnSurface ( double _angle, double _height ) const

{

// Вычисляем координаты точки на основании

Point3D circlePoint = m_base.getPointOn( _angle );

// Создаем новую точку с учетом высоты

return Point3D( circlePoint.getX(), circlePoint.getY(), circlePoint.getZ() + _height );

}

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