Задание следующее:
Написать программу,демонстрирующую работу с объектами двух типов Т1 и Т2,для чего создать систему соответствующих классов. Каждый объект должен иметь идентификатор(в виде произвольной строки символов) и одно или несколько полей для хранения состояния (текущего значения) объекта.
Клиенту(ф-ии main) должны быть доступны следующеие основные операции(методы):создать объект,удалить объект,показать значение объекта и прочие дополнительные операции,которые будут указаны ниже.Операции по созданию и удалению объектов инкапсулировать в классе Factory.Предусмотреть место,позволяющее продемонстрировать заданные операции.
При необходимости в разрабатываемые классы добавляются дополнительные методы(например,конструктор копирования,операция присваивания и тп)для обеспечения надлежащего функционирования этих классов.
Типы объектов
Класс \ Объект
-------------------------------------------------
Triangle \ Треугольник
Quadrate \ Квадрат
Rectangle \ Прямоуголник
Tetragon \ Четырёхуголник
Pentagon Пятиугольник
Перечень дополнительных операций
Операция(метод) \ Описание
-------------------------------------------------------------
Move() \ Переместить объект на плоскости
Compare(T& ob1,T& ob2) \ Сравнить объект 1 и 2 по площади
IsIntersect(T& ob1,T& ob2) \ Определить факт пересечения объектов 1,2(есть\нет)
IsInclude(T& ob1,T& ob2) \ Определить факт включения объекта 2 в объект 1.
T1 \ T2 \ Операция(Метод)
----------------------------------------------
Triangle \ Pentagon \ Move(),Compare(T&,T&)
дык вот....я даже не знаю с чего начать...
помогите,пожалуйста.
#include "iostream.h"
// Базовый класс для всех фигур, чтобы были возможны, например,
// операции сравнения площади в любых вариантах
class TFigure {
public:
TFigure(const char *s = ""): name(s) {
cout << name << " created ..." << endl;
}
// чисто виртуальный метод, вычисление площади,
// будет переопределяться в каждом производном классе
virtual double getS() const = 0;
protected:
// Название фигуры
const char *name;
};
// Определяем класс - наследник от TFigure
class TTriangle: public TFigure {
public:
// Конструктор... В процессе работы над программой тебе придется
// добавить сюда еще несколько параметров, гарантирующих однозначное
// определение треугольника на плоскости (например, координаты 3-х точек),
// но для начала - "пустышка"
TTriangle() : TFigure("triangle") {
}
// Переопределение метода расчета площади
// (если этого не сделать, то нельзя будет создать экземпляр класса TTriangle,
// т.к. считается, что он содержит неперекрытую ЧИСТО виртуальную функцию)
double getS() const {
return 10.0; // Для простоты будем считать, что ВСЕ треугольники имеют площадь = 10
}
};
class TQuadrate: public TFigure {
public:
// Аналогично, добавить в конструктор необходимые параметры
// для задания квадрата на плоскости
TQuadrate() : TFigure("square") {
}
double getS() const {
return 12.0;
}
};
// Сравнение площадей двух фигур... Возможны любые комбинации, главное,
// чтобы T1 и T2 были потомками (в любом "поколении") TFigure
int Compare(const TFigure &T1, const TFigure &T2) {
// Благодаря виртуальным функциям, вызываются методы getS именно тех классов,
// экземпляры которых переданы как фактические параметры в функцию
return (T1.getS() < T2.getS()) ? -1 : 1;
}
// Основная программа пока умеет немного - только задать один или несколько экземпляров
// одного из вышеопределенных классов ...
int main() {
TTriangle T1;
// ... напечатать площадь этого объекта ...
cout << T1.getS() << endl;
TQuadrate T2;
cout << T2.getS() << endl;
// ... и вывести результат сравнения плохадей в одном порядке ...
cout << Compare(T1, T2) << endl;
// ... и в другом тоже (знаки результатов должны быть противоположными)
cout << Compare(T2, T1) << endl;
return 0;
}
а вот вопросик возник.
когда создаю фигуру,ее создание следует делать по вершинам,так?
есть ли смысл делать структуру ,скажем,ВЕРШИНА для определения координат...
то бишь тогда при задействовании конструктора,надо будет в парметрах написать только названия вершин...
или так нельзя?
и где ее прописывать...за пределами класса или внутри,...тогда какого...
public: // В секции public, потому что нам понадобится доступ и "снаружи"
struct TPoint {
// Конструктор по умолчанию...
TPoint(int px = 0, int py = 0): x(px), y(py) {
}
int x, y;
};
class TTriangle: public TFigure {, а в main() делать так:
private:
TPoint *pts; // указатель на массив TPoint, для хранения вершин
public:
TTriangle(TPoint p1, TPoint p2, TPoint p3) :
TFigure("triangle") {
pts = new TPoint[3]; // берем память под массив
... // и заполняем массив вершинами
}
~TTriangle() {
delete [] pts; // не забываем удалять массив
}
double getS() const {
return 10.0;
}
};
...
TTriangle T1(
TFigure::TPoint(1, 1),
TFigure::TPoint(3, 3),
TFigure::TPoint(5, 5)
);
cout << T1.getS() << endl;
...
вот попыталась сделать конструктор...
я хочу,чтобы при обращении к конструктору запрашивались координаты вершин.так можно делать?
что не так?
вот то,что у меня получилось.
я не очень разобралась с общими методами для фигур,поэтому программа не компилируется.
посмотрите,пожалуйста.
в чем мои ошибки?
Прикрепленные файлы
01.cpp ( 3.01 килобайт )
Кол-во скачиваний: 294
1) ты забыла одну закрывающую скобку (завершающую в функции TFigure::move_it), и получила несколько наведенных ошибок... Кстати, компилятор предупреждает тебя, что функции, содержащие for не будут inline-функциями, поэтому их описания лучше выносить за пределы определения класса...
2)
double getS() const {это неправильно... Чтобы обращаться к точкам, тебе достаточно:
return
0.5*(
TPoint[1].y*TPoint[2].x-TPoint[2].y*TPoint[1].x+
TPoint[2].y*TPoint[3].x-TPoint[3].y*TPoint[2].x-
TPoint[1].y*TPoint[3].x+TPoint[1].y*TPoint[1].x
);
}
double getS() const- обращаться по имени переменной, а не типа... Причем, заметь, массивы в С++ индексируются с 0 а не с 1... Та же самая ошибка у тебя - при попытке считать координаты точек в конструкторе TPentagon...
{
return 0.5 * (pts[0].y*pts[1].x - pts[1].y*pts[0].x +
pts[1].y*pts[2].x - pts[2].y*pts[1].x -
pts[0].y*pts[2].x + pts[0].y*pts[0].x);
}
char Compare(const TFigure &T1, const TFigure &T2)
{
return (T1.getS() < T2.getS()) ? '<' : '>';
}
TTriangle T1;А вот как от этого избавиться - это уже вопрос к тебе: ты все-таки решила, что хочешь вводить координаты точек прямо в конструкторе? Тогда делай именно конструкторы по умолчанию... Для TTriangle, например, такой:
TTriangle(int numPoints = 3) : TFigure("triangle")
{
pts = new TPoint[numPoints];
for(int i=0;i<numPoints;i++)
{
TPoint p;
cout << "Enter coordinates of apex" << i+1 << ":";
cin << p.x << p.y;
pts[i] = p;
}
}
воть...теперь он еще и на ввод-вывод ругается в нескольких местах...почти всех...=(
а если сделать ввод координат вершин вне конструктора,лучше будет?=)
Прикрепленные файлы
02.cpp ( 3.05 килобайт )
Кол-во скачиваний: 320
Смотри, как я переделала классы... Твоя программа стала уже сейчас тяжело читаемой, представляешь, что будет потом?
al_01.cpp ( 4.06 килобайт )
Кол-во скачиваний: 743
огромное спасибо!!!
сейчас со всем разберусь...
а идеи насчет площади пятиугольника у вас нет?
через определитель длинная формула очень будет)
double getS() const
{
double s = 0;
for(int i = 0; i < ptsAmount; i++) {
int j = (i == (ptsAmount - 1)) ? 0 : (i + 1);
s += (pts[i].x - pts[j].x) * (pts[i].y + pts[j].y);
}
return (0.5 * s);
}
а я с площадью сама разобралась!=)
но всё равно огромное спасибо за вашу помощь=)
в этой программе мне нужно задействовать дружественные функции...
не подскажете,как это можно сделать и с какими функциями?
правда на этот раз мне нужно работать с треугольником и прямоугольником,
а действия призводить над ними:перемещение и проверку пересечения этих фигур.
не могу я понять смысл дружестенных функций...поэтому и не могу реализовать их в программе...=(
помогите ,пожалуйста, разобраться что к чему...
Дружественная функция?
Как бы объяснить... Ага... Вот так, наверное:
если у тебя описан такой класс (это никак не связано с твоей задачей, просто пример):
class A {
public:
A(int value) {
x = value;
}
private:
int x;
};
int is_equal(const A &first, const A &second) {
// Вернем 1, если поля "х" обоих классов равны, иначе - 0
return (first.x == second.x) ? 1 : 0;
}
class A {, то здесь уже все будет в пределах правил: доступ из "друга" к приватным полям разрешен...
friend int is_equal(const A&, const A&);
public:
A(int value) {
x = value;
}
private:
int x;
};
int is_equal(const A &first, const A &second) {
return (first.x == second.x) ? 1 : 0;
}
аха...вроде понятно...спасибо большое!=)
а не подскажете,как мне с пересечением справиться(треугольника и прямоугольника)...
я уже и не знаю что с ними делать...координаты сравнивать как-то глупо...с уравнениями прямых тоже нельзя работать...как быть?
а если использовать этот алгоритм для проверки пересечения в оем случае,как лучше поступить с зданием вешин?
http://algolist.manual.ru/maths/geom/intersect/convex_intersect.php
Точка - она и в Африке точка, так что будет работать (если запрограммируешь сам алгоритм правильно) и с таким заданием, как это сделано в сообщении №9... Возиожно придется массив точек заменить на список, или какой-то еще другой класс, но желательно, чтобы все вершины были известны уже в базовом классе...
Кстати, прежде, чем прикручивать этот алгоритм к твоей программе, сделай его отдельно (и прогони хотя бы несколько тестов), убедись что все правильно работает, и только потом перекраивай весь проект, а то начнешь, будет работать неверно - подумаешь, что ошиблась при переделке, потеряешь кучу времени, а это в самом алгоритме недочет какой-нибудь...
в общем я решила сравнивать координаты максимумов и минимумов в зависимости от положения фигур друг относительно друга....
есть проблемы с ф-ией определения min\max...ругается,что непостоянная ф-ия вызывается для постоянного объкта...как этого избжать?
и у меня нет идей,какую ф-ию можно сдлать дружественной...
Прикрепленные файлы
03.cpp ( 3.96 килобайт )
Кол-во скачиваний: 419
изменила код выше
воть....как думаете по какой причине можт IsIntersect неправильно результат иногда выдавать?=(
Прикрепленные файлы
04.cpp ( 3.56 килобайт )
Кол-во скачиваний: 392
Приведи пример ввода, на котором выдаются неправильные результаты...
например,
треугольник
0 0
0 5
5 0
прямоугольник
1 1
1 5
5 5
5 1
не помогло даже добавление вроде как необходимого альтернативного варианта включения вершины другой фигуры,ведь первая не обязательно содержит вершины второй,но тогда вторая-обязаельно...
if ((T1->IsInside(T2->pts[i].x,T2->pts[i].y))||(T2->IsInside(T1->pts[i].x,T1->pts[i].y))) {flag=true;break;};
всё)сообразила..всё дело было в типах
Это задача из учебника Павловской "Объектно-ориентированное программирование. Практикум", стр 102
Препод мне тоже дал эту задачу, причем сдавать мне ее надо сегодня (именно СЕГОДНЯ!!!! через 15 мниут выезжаю). Я даже не расчитывал седня сдать, но благодаря Tribunal`у, Алене, volvo, а также Яндексу и Опере мои планы резко изменились))). Как бы сказал мой препод "Радость моя огромна":)))).
В связи в этим хочу выразить искреннюю благодарность всем перечисленным выше лицам (и программам), в особенности Tribunal, за практически готовый исходник программы про треугольники и прямоугольники.
Извините, а ктонибудь не может немного переписать эту прогу так, чтобы объекты не создавались сами(т.е. автоматически), а чтобы было меню, где можно было бы выбрать создание объекта. И с удалением тоже самое. Сам пробовал, но компилироваться не хочет. Я так понял, что создание прописано в конструкторе. Но ведь конструктор же вызвать нельзя, => надо создание извлеч из конструктора и поместить в дружественную ф-ию, я так понял. Но простое копирование не проходит. Находит много ошибок. Помогите начинающему программеру пожалуйста.
Я использовал последний пример от Tribunal.
Так вот я делал так:
Для создания объекта допустим ф-ия:
TFigure::Great(int numPoints, const char *s = ""):name(s), ptsAmount(numPoints)
{
pts = new TPoint[ptsAmount];
cout << name << " created ..." << endl;
for(int i = 0; i < ptsAmount; i++)
{
TPoint p;
cout << "Enter coordinates of apex" << i+1 << ":";
cin >> p.x >> p.y;
pts[i] = p;
}
}
и для удаления:
TFigure::del(void)
{
TFigure;
}
Понимаю, что что то надо изменить, но не знаю что. И в таком случае, если эти ф-ии будут как дружественные, то что следует писать в конструкторе: конструктор по умолчанию?
Я, кстати, только что заметил ошибку в твоих рассуждениях:
т.е. мне надо написать в ф-ии main: new *T1, *T2; или как, я всё равно не понимаю, и как потом вызывать? Не можешь написать это кодом, применительно к моей проге?