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

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

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.02.2014, 00:55   #1
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию Абстрактные классы

Здравствуйте, дорогие форумчане.
Скажу сразу, задание помогаю делать знакомой, и обычно проблем не возникало никаких с её заданиями, но в этот раз.. Я от задания сам стал находится в небольшом шоке.. В общим, хороший такой пробел у меня по абстрактным классам, меня в универе по ним не гоняли ((
Собственно, проблема такая (выложу пока её часть, по мере решения буду код ещё давать).
Итак, задание. В него ещё вникал некоторое время:
Цитата:
Реализации всех классов, а также основная функция программы, должны быть разнесены по различным файлам исходного текста и использовать соответствующие заголовочные файлы.

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

Создать абстрактный базовый класс Pair с виртуальными арифметическими операциями. Создать производные классы Money (задание 1.24) и Fraction (задание 1.35).
Задание 1.35
Создать класс Fraction для работы с дробными числами. Число должно быть представлено двумя полями: целая часть - длинное целое со знаком, дробная часть - беззнаковое короткое целое. Реализовать арифметические операции сложения, вычитания, умножения и операции сравнения.
Во-первых, для меня было уже откровением, что есть чисто абстрактные методы.
Немного погуглив, приступил к реализации.
Вот, что пока вышло.
Код pair.h:
Код:
class Pair
{
public:
	Pair();
	~Pair();
	virtual void read() = 0;
	virtual void write() = 0;
	virtual Pair& operator=(Pair &other) = 0;
	virtual Pair& operator+(Pair &other) = 0;
};
Код pair.cpp:
Код:
#include "pair.h"

Pair::Pair()
{

}

Pair::~Pair()
{

}
Код fraction.h:
Код:
#include "pair.h"

class Fraction : public Pair
{
public:
	Fraction();
	Fraction(Fraction &other);
	Fraction(long numerator, long denominator);
	~Fraction();
	void read();
	void write();
	virtual Pair& operator=(Pair &other);
	virtual Pair& operator+(Pair &other);

protected:
	virtual Pair& operator=(Fraction &other);
	virtual Pair& operator+(Fraction &other);

private:
	unsigned short denominator;
	long numerator;
};
Код fraction.cpp:
Код:
#include <iostream>
#include "fraction.h"

using namespace std;

long gcd(long a, long b)
{
	return b ? gcd(b, a % b) : a;
}

void normalize(long &numerator, long &denominator)
{
	long n;
	if (denominator < 0)
	{
		numerator = -numerator;
		denominator = -denominator;
	}
	if (numerator == 0 || denominator == 0)
	{
		denominator = 1;
	}
	n = gcd(abs(numerator), abs(denominator));
	numerator /= n;
	denominator /= n;
}

Fraction::Fraction()
{
	numerator = 0;
	denominator = 1;
}

Fraction::Fraction(Fraction &other)
{
	this->numerator = other.numerator;
	this->denominator = other.denominator;
}

Fraction::Fraction(long numerator, long denominator)
{
	normalize(numerator, denominator);
	this->numerator = numerator;
	this->denominator = denominator;
}

Fraction::~Fraction()
{

}

void Fraction::read()
{
	cout << "Введите числитель: ";
	cin >> numerator;
	cout << "Введите знаменатель: ";
	cin >> denominator;
}

void Fraction::write()
{
	cout << numerator << " / " << denominator;
}

Pair& Fraction::operator=(Pair &other)
{
	cout << "operator=Pair" << endl;
	*this = *(Fraction*)&other;
	return *this;
}

Pair& Fraction::operator+(Pair &other)
{
	cout << "operator+Pair" << endl;
	//return other + *this; - it doesn't work Oo
	return *(Fraction*)&other + *this;
}

Pair& Fraction::operator=(Fraction &other)
{
	cout << "operator=Fraction" << endl;
	this->numerator = other.numerator;
	this->denominator = other.denominator;
	return *this;
}

Pair& Fraction::operator+(Fraction &other)
{
	cout << "operator+Fraction" << endl;
	//return Fraction(10, 8);
	return *(new Fraction(this->numerator * other.denominator + other.numerator * this->denominator, this->denominator * other.denominator));
}
Код main.cpp:
Код:
#include <cmath>
#include <iostream>
#include <locale>
#include "fraction.h"
 
using namespace std;
 
int main()
{
	Pair* a;
	Pair* b;
	Pair* c;
	cout.setf(ios::fixed);
	cout.precision(2);
	setlocale(LC_ALL, "Rus");
	a = new Fraction();
	a->read();
	b = new Fraction();
	b->read();
	c = new Fraction();
	*c = *a + *b;
	cout << "c = ";
	c->write();
	cout << endl;
   
	delete a;
	delete b;
	delete c;
	return 0;
}

Последний раз редактировалось Vadik(R); 23.02.2014 в 01:55. Причина: Обновил fraction.h и fraction.cpp
Vadik(R) вне форума Ответить с цитированием
Старый 23.02.2014, 00:56   #2
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию

Теперь мои комментарии к коду и вопросы. То, что write - это метод, а не оператор, << пишущий в ostream - опустим, примут, не сложно переделать.
Насчёт использования
Код:
virtual Pair& operator=(Pair &other);
virtual Pair& operator=(Fraction &other);
вообще не уверен, просто спустя большое количество просиженных часов, и перепробовав методом перебора кучу способов так, чтобы заработало, как-то сами собой эти строчки у меня получились. Возможно они и не нужны, жду подсказок от гуру, как нужно делать такие задания
Далее, собственно вопросы.
Наткнулся на такой полезный учебник, который и читал. А именно, вот: http://www.cap-design.ru/ccc/130.htm
Сделал всё по аналогии, но почему-то у меня не работает участок кода, как у них:
Код:
Pair& Fraction::operator+(Pair &other)
{
	cout << "operator+Pair" << endl;
	//return other + *this; - it doesn't work Oo
	return *(Fraction*) &other + *this;
}
Он не подставляет дальше всё (закоменченную строчку) в
Код:
Pair& Fraction::operator+(Fraction &other)
Почему - не в курсе, но он рекурсивно вызывает сам себя и вылетает (для того cout и поставил )
Это первый такой, основной вопрос. Я его решил приведением типа (но это же не профессионально, да?)
Тогда встал второй вопрос.
Код:
Pair& Fraction::operator+(Fraction &other)
{
	cout << "operator+Fraction" << endl;
	//return Fraction(10, 8);
	return *(new Fraction(this->numerator * other.denominator + other.numerator * this->denominator, this->denominator * other.denominator));
}
Если я создаю просто объект, то он не всегда корректно потом выводит значения. Было return Fraction(5, 6);, c->write() в коде нормально работал (т. е. всегда писал 5 / 6). А вот на дробь 10 / 8 он почему-то стал выводить совсем другие значения.
return *new Fraction....
В общем, возврат значение указателя - в этом случае сложение происходит корректно. Но есть утечка памяти, что есть очень плохо. Проверяется:
Код:
for (unsigned int i = 0; i < 10000000; i++)
{
	*c = *a + *b;
}
//для паузы
a->read();
Вот в таком случае явно видно, что занятая оперативная память около 400 Мб.

В общем, любые комментарии, помощь - приветствуются. Мне это важно не только, чтобы знакомой сделать лабу, а чисто для себя.
В олимпиадном программировании и собственном быдлокодинге абстрактные классы никак мне не пригодились, а вот при устройстве на работу, чувствую, вполне возможны вопросы по абстрактным классам на собеседовании. Заранее всем спасибо

Последний раз редактировалось Vadik(R); 23.02.2014 в 01:56.
Vadik(R) вне форума Ответить с цитированием
Старый 23.02.2014, 01:56   #3
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию

Для удобства добавил сам проект
Вложения
Тип файла: rar test.rar (4.6 Кб, 59 просмотров)
Vadik(R) вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
абстрактные классы в С# gvozdik12 Помощь студентам 11 05.06.2013 13:33
Абстрактные классы aaayyy HTML и CSS 2 02.07.2012 09:54
Абстрактные классы KuckaMAXHATKA Общие вопросы C/C++ 1 13.12.2011 23:29
Абстрактные классы romantik2011 PHP 2 27.07.2011 10:36
С++ Абстрактные классы Jane-sad Помощь студентам 2 14.10.2010 14:19