Нужны советы (по использованию ООП в С++)

Модератор: Модераторы разделов

Аватара пользователя
Assuri
Сообщения: 678
Статус: #include <brain.h>
ОС: Fedora 12

Нужны советы

Сообщение Assuri »

Я хочу попросить уже сложившихся программистов дать пару советов или упреков мне по поводу использования ООП. То-есть: лучше бы сделал так, а не так; этого делать не надо было; попробуй применить то и т.д.

Программу, которую я выбрал для практики - проста. Это калькулятор, выполняющий 4-ре действия. Вот код этого калькулятора ( все работает ):

Код:

#include <iostream> using namespace std; class calculator { private: double number1, number2; double result; char op,quast; bool how; public: bool qyet; calculator () : number1 ( 0.0 ), number2 ( 0.0 ), result( 0.0 ) { } void print_tasks() { cout << "Введите действие, которое вы хотите совершить. \n"; do { cout << "+ - сложить числа \n- - вычесть числа \n* - умножить числа\n/ - делить числа \n>"; cin >> op; how = check_op(); } while ( how != true ); } bool check_op() { if ( op != '-' && op != '+' && op != '*' && op != '/') return false; else return true; } void scan_numbers() { cout << "1-ое число >"; cin >> number1; cout << "2-ое число >"; cin >> number2; } void print_result() { cout << "Результат вычеслений: " << result << '\n'; } void quastion() { cout << "Есть ли у вас еще какие-нибудь вычесления? (y/n) >"; cin >> quast; if ( quast == 'y') qyet = true; else qyet = false; cout << '\n'; } void count (); }; void calculator::count() { switch ( op ) { case '*': result = number1 * number2; break; case '/': if ( number2 == 0) cout << "Ошибка: делить на ноль нельзя \n"; result = 0; break; case '+': result = number1 + number2; break; case '-': result = number1 - number2; } } int main() { calculator calc; do { calc.print_tasks(); calc.scan_numbers(); calc.count(); calc.print_result(); calc.quastion(); } while (calc.qyet != false ); return 0; }

Заранее, спасибо.
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: Нужны советы

Сообщение oav »

Так, собсна, в чем вопрос? Я не вижу ООП, вижу несколько функций, которые оперирует с состоянием из 5 переменных (в логику реализации не смотрел).
Поэтому не понятно что хочет автор топика...
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Нужны советы

Сообщение Zeus »

Соглашусь с oav'ом.

В ООП в C++ реализуется через:
1. Наследование.
2. Виртуальные функции.
3. Указатели.
Спасибо сказали:
Аватара пользователя
dey
Сообщения: 335
ОС: OpenSuse 11.1

Re: Нужны советы

Сообщение dey »

Имхо задача слишком тривиальная и распространенная , чтоб ее здесь мусолить
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Нужны советы

Сообщение v04bvs »

-DooM- писал(а):
04.07.2007 14:47
Я хочу попросить уже сложившихся программистов дать пару советов или упреков мне по поводу использования ООП. То-есть: лучше бы сделал так, а не так; этого делать не надо было; попробуй применить то и т.д.

Программу, которую я выбрал для практики - проста. Это калькулятор, выполняющий 4-ре действия. Вот код этого калькулятора ( все работает ):

Код:

#include <iostream> using namespace std; // есть сложившаяся практика использовать UppercaseName для названия небиблиотечных классов class calculator { private: double number1, number2; double result; char op,quast; // нет пробела после запятой bool how; // есть сложившаяся практика выделять private members как нибудь, я предпочитаю префикс m_ public: // нельзя делать public fields, и ещё название кажется неграмотно bool qyet; calculator () : number1 ( 0.0 ), number2 ( 0.0 ), result( 0.0 ) { } // метод слишком большой, его не надо inline-нить void print_tasks() { // в исходном коде символы, отличные от ASCII, этого следует избегать всеми способами. В данном случае русская строка должна грузиться из внешнего файла ресурсов cout << "Введите действие, которое вы хотите совершить. \n"; // не выводится сообщение об ошибке в случае неверного ввода. Confusing do { cout << "+ - сложить числа \n- - вычесть числа \n* - умножить числа\n/ - делить числа \n>"; cin >> op; how = check_op(); } while ( how != true ); } // метод должен быть константным bool check_op() { // ненужное усложнение, достаточно return ! ( op != '-' && op != '+' && op != '*' && op != '/'); и дальше по правилам Де-Моргана раскрыть скобки if ( op != '-' && op != '+' && op != '*' && op != '/') return false; else return true; } void scan_numbers() { // нет проверки на правильность ввода cout << "1-ое число >"; cin >> number1; cout << "2-ое число >"; cin >> number2; } // метод должен быть константным void print_result() { cout << "Результат вычеслений: " << result << '\n'; } // неграмотный английский, советую установить спеллчекер в вашу IDE, порой очень помогает void quastion() { cout << "Есть ли у вас еще какие-нибудь вычесления? (y/n) >"; // нет проверки на корректность ввода, на конец файла cin >> quast; if ( quast == 'y') qyet = true; else qyet = false; cout << '\n'; } void count (); }; void calculator::count() { switch ( op ) { case '*': result = number1 * number2; break; case '/': if ( number2 == 0) cout << "Ошибка: делить на ноль нельзя \n"; result = 0; break; case '+': result = number1 + number2; break; case '-': result = number1 - number2; } } int main() { calculator calc; do { calc.print_tasks(); calc.scan_numbers(); calc.count(); calc.print_result(); calc.quastion(); } while (calc.qyet != false ); return 0; }

Заранее, спасибо.

В целом мы видим программу в классическом процедурном стиле с очень большим использованием глобальных переменных, замаскированную под объектный стиль. Позже могу провести ряд простых рефакторингов, которые превратят её в что-то лучшее. Так же напрягают некоторые мелочи вроде пробелов там где не надо (или отсутствия их там, где надо).
Спасибо сказали:
Аватара пользователя
uptime
Сообщения: 1661
Статус: Drinker with computing problems
ОС: kubuntu 8.04

Re: Нужны советы

Сообщение uptime »

v04bvs писал(а):
04.07.2007 17:02
...Так же напрягают некоторые мелочи вроде пробелов там где не надо (или отсутствия их там, где надо).

и олбанский английский в названиях переменных и функций...
The answer, my friend, is blowin' in the wind.
The answer is blowin' in the wind.
Спасибо сказали:
Аватара пользователя
Assuri
Сообщения: 678
Статус: #include <brain.h>
ОС: Fedora 12

Re: Нужны советы

Сообщение Assuri »

А что мне добавить или переделать, чтобы было похоже не на процедруное программирование, а ООП? Хоть немного...

uptime писал(а):
04.07.2007 17:07
v04bvs писал(а):
04.07.2007 17:02
...Так же напрягают некоторые мелочи вроде пробелов там где не надо (или отсутствия их там, где надо).

и олбанский английский в названиях переменных и функций...

Это по мере изучения англа приходит..
Спасибо сказали:
Аватара пользователя
Фантом
Сообщения: 463
ОС: openSUSE

Re: Нужны советы

Сообщение Фантом »

-DooM- писал(а):
04.07.2007 18:17
А что мне добавить или переделать, чтобы было похоже не на процедруное программирование, а ООП? Хоть немного...


Сменить условие задачи. :)

ООП - штука мощная и полезная, но это не значит, что им надо пытаться затыкать любую дырку. Круг задач, для которых использование ООП дает существенные преимущества, на самом деле не так уж и велик; во всех остальных случаях (в т.ч. и в рассматриваемом) использование ООП напоминает попытку почесать правой ногой левое ухо - сложно, неестественно и предельно неэффективно.
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Нужны советы

Сообщение Uncle_Theodore »

Есть такая английская поговорка: Человек, который в своей жизни научился только хорошо обращаться с молотком, пытается решить любую проблему путем забивания гвоздей... :)
К сожалению учителя компьютерных наук по обе стороны океана оказались настолько зомбированными объектно-ориентированным подходом, что создают у студентов впечатление, что методы ООП универсальны, и решают любую проблему. В США на такой путь их привела не к ночи будет помянута, компания SUN Microsystems, которая в подсаживании американского образования на свою Джаву не останавливалась ни перед чем.
У ООП есть узкая ниша применения. Вне ее ООП -- неуклюжая и вредная парадигма, которая иссушает мозги. Для написания калькулятора ООП нафиг не нужно, например. :)

Вот такое ИМХО.
Спасибо сказали:
Аватара пользователя
Assuri
Сообщения: 678
Статус: #include <brain.h>
ОС: Fedora 12

Re: Нужны советы

Сообщение Assuri »

Я был бы рад, если бы Вы привели примеры условий задач, где использование ООП является желательной состовляющей программы.
Спасибо сказали:
Аватара пользователя
Фантом
Сообщения: 463
ОС: openSUSE

Re: Нужны советы

Сообщение Фантом »

-DooM- писал(а):
09.07.2007 10:21
Я был бы рад, если бы Вы привели примеры условий задач, где использование ООП является желательной состовляющей программы.


Есть два варианта подбора задач.

1) Моделируемая "действительность" должна наиболее естественно представляться в виде набора многочисленных объектов с теми или иными свойствами, причем эти объекты должны существенным образом взаимодействовать. Каждый конкретный вид действий того или иного объекта легко алгоритмизируется, но алгоритм, описывающий поведение всей системы в целом, сформулировать сложно.

Важно, что объектов должно быть действительно много, а зависимости между ними должны быть достаточно сложными. Иначе нет смысла городить огород.

Наиболее банальный (и чаще всего встречающийся в действительности) пример - оконные интерфейсы. Еще один пример того же рода - взаимодействие между процессами в многозадачной ОС (или между узлами в кластере). Это основная (и, по большому счету, единственная) область, в которой ООП действительно нужно.

2) При написании требуется создать большое количество "однотипного" кода, в каждый вариант которого внесены небольшие изменения. При этом требуется сохранить возможность легкого дописывания новых вариантов.

В подобной ситуации имеющиеся в ООП наследование и полиморфизм могут помочь. Правда, задачи, в которых такое надо, обычно относятся к числу экзотических.

Итог. При реальном использовании ООП программа должна быть большой и отличаться сложными внутренними связями. 99% программистов "с нуля" такое не пишут, почти всегда используется уже созданная ранее библиотека классов. Соответственно, изучать ООП имеет смысл путем написания программ, использующих какую-нибудь библиотеку такого рода.
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Нужны советы

Сообщение Uncle_Theodore »

Есть еще классические примеры с рисовалками. Когда определяем класс Shape и наследуем от него классы Circle и Polygon, от Polygon'а наследуем классы Triangle, Square, Rectangle и т.д. Смысл в том, чтобы определить функцию draw() в классе Shape и оверлодить ее в производных классах. Потом определяем массив ссылок на Shape, и в одном цикле их всех рисуем.
Попробуй, забавно... :)
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: Нужны советы

Сообщение Zeus »

Uncle_Theodore писал(а):
09.07.2007 19:36
Потом определяем массив ссылок...

...указателей.
Спасибо сказали: