Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.05.2008, 16:34   #1
Lioness
Пользователь
 
Аватар для Lioness
 
Регистрация: 03.01.2008
Сообщений: 20
Стрелка Конструктор, наследование, перегрузка операций

Пожалуйста, помогите решить задачу. Решена наполовину. Выкладываю полностью, с тем что решила и с тем, где непонятно.

Задание 1 (сделано ниже)
Создать класс "Круг" на координатной плоскости. Данные класса - координаты центра круга и радиус. Класс имеет конструктор по умолчанию, конструктор круга единичного радиуса, и конструктор произвольного круга. Определить методы для ввода круга, вывода на экран и определения длины окружности и площади круга.
1. Определить объекты созданного типа, обратиться к методам.
2. Определить указатель на объект созданного типа, обратиться к методам.
3. Определить метод Show для графической иллюстрации объектов класса.
Код:
#include <stdio.h>
#include <graphics.h>

class Krug
{
int x;
int y;
float r;

public:
Krug ()
{
x=y=0;
r=1;
}
Krug (int x1, int y1, float r1)
{
  x=x1;
  y=y1;
  r=r1;
}
void Out()
{
  printf("x=%d,y=%d,r=%f\n",x,y,r);
  }
void Show()
{
setcolor(GREEN);
circle (x,y,r);
}
void Show_fill()
{
setfillstyle (2,GREEN);
fillellipse (x,y,r,r);
}
};
void main(void)
{
Krug Vasya;
Vasya.Out();

Krug Petya(150,170,20);
Petya.Out();

int gdriver=DETECT,gmode,errorcode;
initgraph (&gdriver,&gmode,"c:\\bc31\\bgi")

Vasya.Show();
Petya.Show_fill();
}


Задание 2 (сделан только 1 пункт, ниже)
1. Перегрузить операции сложения, вычитания для кругов с использованием операции - метода класса и дружественной функции.
2. Перегрузить унарную операцию ++ для инкремента радиуса круга как метод класса, а -- как дружественную функцию.

#include <stdio.h>
#include <graphics.h>

class Krug
{
int x;
int y;
float r;

friend void operator + (Krug & T1, Krug &T2);
friend void Inc_y (Krug&);
friend void Inc_r (Krug&);

public:
Krug ()
{
x=y=0;
r=1;
}
Krug (int x1, int y1, float r1)
{
  x=x1;
  y=y1;
  r=r1;
}
void Out()
{
  printf("x=%d,y=%d,r=%f\n",x,y,r);
  }
Krug operator - (Krug T2)
{
Krug T(0,0,0);
T.x=(x-T2.y)*0.5;
T.y=(y-T2.y)*0.5;
T.r=(this-> r-T2.r)*0.5;
return T;
}
int Sum(Krug &A)
{
return A.x+A.y;
}
}; // End of Krug

Krug operator + (Krug &T1, Krug &T2)
{
Krug T(0,0,0);
T.x=(x+T2.y)*0.5;
T.y=(y+T2.y)*0.5;
T.r=(this-> r+T2.r)*0.5;
return T;
}
void main (void)
{
Krug.A(5,7,5);
A.Out()
Krug B (3,5,7);
Krug C;
C=A+B;
C.Out(); // (8,12)
C=A-B;
C.Out();
}
в этой задаче решено только 1е задание, помогите сделать 2е (2. Перегрузить унарную операцию ++ для инкремента радиуса круга как метод класса, а -- как дружественную функцию.)
и еще:

Задание 3
Наследуемым классом для круга объявить класс "Кольцо", имеющий дополнительный радиус (внутренний) и метод "Площадь". Определить конструктор кольца. Вывести данные на экран с использованием метода базового класса.


буду благодарна любой помощи!!!

Последний раз редактировалось Stilet; 29.05.2008 в 16:37.
Lioness вне форума Ответить с цитированием
Старый 29.05.2008, 17:38   #2
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Ну насчет перегрузки ++ то это легко.
Код:
Krug operator++(Krug &T1)
{
	int tmpRadius=0;
	tmpRadius=T1.r;
	tmpRadius=tmpRadius+1;
	T1.r=tmpRadius;
	return T1;
}
MaTBeu вне форума Ответить с цитированием
Старый 29.05.2008, 17:45   #3
Lioness
Пользователь
 
Аватар для Lioness
 
Регистрация: 03.01.2008
Сообщений: 20
По умолчанию

Цитата:
Сообщение от MaTBeu Посмотреть сообщение
Ну насчет перегрузки ++ то это легко.
Код:
Krug operator++(Krug &T1)
{
	int tmpRadius=0;
	tmpRadius=T1.r;
	tmpRadius=tmpRadius+1;
	T1.r=tmpRadius;
	return T1;
}
спасибо))) а унарная -- другая совсем?
Lioness вне форума Ответить с цитированием
Старый 29.05.2008, 18:15   #4
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

А вот мой вариант унарной -- (хотя скажу сразу, может быть неверно)
Код:
Krug operator--()
{
	int tmpRadius=0;
	tmpRadius=this->r;
	tmpRadius=tmpRadius-1;
	this->r=tmpRadius;
	return this;
}
Если что сильно не пинать!
MaTBeu вне форума Ответить с цитированием
Старый 29.05.2008, 19:43   #5
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Вижу конструктор произвольного и единичного кругов, но не вижу по умолчанию.
Не вижу некоторых методов. Не вижу объявления указателя на объект и его использования.
Список инициализации в конструкторах желателен.
Непонятно, зачем в + передавать по ссылке.
Непонятно, зачем в - передавать по значению.
Возвращаемое значение в + и - желателен атрибут const (можно вдобавок inline).
В + и - можно сразу вызвать конструктор произвольного круга, повышая вероятность того, что будет применена оптимизация возвращаемого значения.
Непонятно зачем методу ++ принимать какой-то параметр.
Нет перегрузки постфиксного ++.

PS еще friend void operator + и Krug operator +.

Код, к сожалению, не могу сейчас написать - так как убиваю время машграфом. Сессия близится...

Последний раз редактировалось still_alive; 29.05.2008 в 19:49. Причина: добавлено
still_alive вне форума Ответить с цитированием
Старый 29.05.2008, 19:56   #6
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

А вы не слышали, что при вызове перегруженной операции ++ обращение идет к двум функциям. Одна из них с параметром(ами), а другая - без. Я написал с параметрами. Или это критическая ошибка, из-за которой программа работать не будет?
MaTBeu вне форума Ответить с цитированием
Старый 29.05.2008, 20:16   #7
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Цитата:
А вы не слышали
Во-первых, на "ты"
Не слышал. Мне просто непонятно, зачем нужен тот параметр при передаче в метод, где есть указатель на данный экземпляр, прошу объяснить.
still_alive вне форума Ответить с цитированием
Старый 31.05.2008, 10:30   #8
Lioness
Пользователь
 
Аватар для Lioness
 
Регистрация: 03.01.2008
Сообщений: 20
По умолчанию

нам преподаватель сказала всегда задавать параметры)))
и кстати с третьей задачей никто не поможет? надо ко вторнику сдавать, а у меня проблема с написанием кода... вот набросала, надо что-то типа этого:
Код:
class Kolco: public Krug
{
int rv; //vnutrennij radius
int s; //ploshad
public:
{
rv=rv1;
}
void Out()
{
printf("rv=%d\n",rv);
}
void Ploshad()
{
s=3.14*(rv*rv);
}
};
Lioness вне форума Ответить с цитированием
Старый 31.05.2008, 13:25   #9
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

По третьему заданию. Там нужно кое-что в базовом классе подправить. Если вы хотите вывести элементы производного класса с помощью функции базового, то нужно обьявить эту функцию виртуальной. А в производном классе задать другую ее реализацию. Вследствие чего компилятор сам определит, какую из них использовать, в зависимости от класса.
Вот код Кольца
Код:
class Ring:public Krug
{
        public:
                Ring( int, int, int, int );                     //Конструктор

                int Square();                                   //Вычисление площади
                virtual void Out();                             //виртуальная функция вывода

        private:
                int iRadius;                                    //внутренний радиус
};

Ring::Ring( int tmpRadius, int xC, int yC, int Radius )         
:iRadius(tmpRadius)                                             //строка инициализации (присвоение значения внутреннего радиуса)
{
        x=xC;                                                   //получение координат центра
        y=yC;                                                   //
        r=Radius;                                               //получение радиуса (внешнего)
}

int Ring::Square()                                            //вычисление площади
{                                                                  
        int sqr=0;
        sqr=(3.14*(r*r))-(3.14*(iRadius*iRadius));              //вычисляем площадь по формуле 
        return sqr;                                             //возврат полученного значения
}

void Ring::Out()
{
        cout<<"Х-координата центра:\n"<<x<<"\nY-координата центра\n"     
            <<y<<"\nВнешний радиус\n"<<r<<"\nВнутренний радиус\n"<<iRadius<<"\n";                           

//извините, не дружу я с printf() и scanf() :)
}
Что-то вроде этого. А площадь кольца вычисляется по формуле площадь круга с внешним радиусом минус площадь круга с внутренним радиусом.
MaTBeu вне форума Ответить с цитированием
Старый 31.05.2008, 16:00   #10
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Цитата:
нам преподаватель сказала всегда задавать параметры)))
Преподаватель всегда права. Лучше не спорить)

Вообще пример для наследования выбран неудачно. Как связаны кольцо и круг? Кольцо - не круг, а круг - не кольцо)

Совсем маленький пример:
Код:
#include <iostream>

static const double PI = 3.1415926;

class CCircle {
public:
    CCircle(int cX, int cY, double cR);
    virtual double square();
    virtual void showData();

protected:
    double r;

private:
    int x, y;
};

CCircle::CCircle(int cX, int cY, double cR):
    x(cX), y(cY), r(cR)
{
}

double CCircle::square()
{
    return PI*r*r;
}

void CCircle::showData()
{
    std::cout << x << " " << y << " " << r << " ";
}

class CRing: public CCircle {
public:
    CRing(int cX, int cY, double cR1, double cR2);
    double square();
    void showData();

private:
    double r2;
};

CRing::CRing(int cX, int cY, double cR1, double cR2):
    CCircle(cX, cY, cR1), r2(cR2)
{
}

double CRing::square()
{
    return PI * (r-r2) * (r+r2);
}

void CRing::showData()
{
    CCircle::showData();
    std::cout << r2 << " ";
}

int main()
{
    CCircle *circle = new CCircle(10, 20, 5);
    CRing *ring = new CRing(30, 40, 30, 10);
    CCircle *reallyRing = new CRing(50, 60, 40, 15);

    std::cout << circle->square() << std::endl;
    std::cout << ring->square() << std::endl;
    std::cout << reallyRing->square() << std::endl;

    circle->showData();
    ring->showData();
    reallyRing->showData();

    delete ring;
    delete circle;
    delete reallyRing;

    std::cin.get();
    return 0;
}
2MaTBeu
Цитата:
Если вы хотите вывести элементы производного класса с помощью функции базового, то нужно обьявить эту функцию виртуальной.
Виртуальные функции в данном контексте не в теме. Если они тут и нужны, то только для того, чтобы вывод данных и подсчет площади всегда выполнялись корректно.

Так как насчет ответа на мой вопрос о параметре?
still_alive вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Одиночное наследование Виртуальные функции Brunette Помощь студентам 3 08.05.2008 19:23
Наследование: абстрактный класс zak Общие вопросы C/C++ 4 22.12.2007 13:49
Конструктор запросов kaa БД в Delphi 12 20.12.2006 16:45