Russian Qt Forum
Ноябрь 23, 2024, 17:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3 4 ... 13   Вниз
  Печать  
Автор Тема: Как писать ООП программы?  (Прочитано 86739 раз)
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #15 : Февраль 19, 2014, 07:30 »

Цитировать
Если все используют UML, то подскажите: где скачать? как использовать? И дайте, пожалуйста, ссылку на простой и доступный туториал Улыбающийся
А кто то этой штукой пользуется?

http://habrahabr.ru/post/153353/
Цитировать
Используете ли вы UML?
3%(122)    Пользуюсь постоянно (очень нужный инструмент)
18%(664)    Иногда бывает полезен
0%(17)    К сожалению, довольно часто приходится пользоваться
6%(234)    Приходится пользоваться, но слава богу - не часто
55%(2039)    Не пользуюсь
18%(661)    Не пользуюсь, но подумываю
« Последнее редактирование: Февраль 19, 2014, 08:10 от deMax » Записан
Akon
Гость
« Ответ #16 : Февраль 19, 2014, 09:33 »

8Observer8: Не тратьте время на бесполезные примеры, их развитие и т.п. Беритесь сразу за реальную (полезную) задачу. Применить ООП  можно и в ней. Когда вы реализуете то, что изначально у вас в голове, вы находитесь на более глубоком уровне понимания и ООП реализацию увидеть будет легче.
Записан
8Observer8
Гость
« Ответ #17 : Февраль 19, 2014, 10:01 »

8Observer8: Не тратьте время на бесполезные примеры, их развитие и т.п. Беритесь сразу за реальную (полезную) задачу. Применить ООП  можно и в ней. Когда вы реализуете то, что изначально у вас в голове, вы находитесь на более глубоком уровне понимания и ООП реализацию увидеть будет легче.

Спасибо за совет! Я не так уж и много трачу времени на примеры. Просто мне так легче понимать отдельные принципы ООП. "Полезную" задачу очень трудно придумать, так как уже почти всё реализовано другими программистами.

А кто то этой штукой пользуется?

Я так понимаю, что удобнее всего использовать программу doxygen, так как она генерирует и диаграммы наследования. Примером может служить документация для Qwt: http://qwt.sourceforge.net/class_qwt_plot.html

Подкинуть идей - ну так, наскидку, трудновато. Впрочем один я уже подкинул (с тенью окна, см выше). Хорошо, вот еще
- в классическом примере с фигурами утверждается что "каждая фигура умеет себя рисовать", это полиморфный метод. Какие недостатки у такого решения? Так ли уж оно бесспорно? Можно ли привести пример когда оно оказывается неудачным?

Igors, Спасибо! Я помню про тот пример. Вернусь к нему позже. Спасибо за новый! Хороший пример. Как раз то, что нужно. Но пока не готов ответить.

Цитировать
Примечание. При сложении и вычитании дробей: к общему знаменателю привожу - перемножением, результат не сокращаю.

Это плохо(
Во-вторых, хотелось бы иметь операторы сравнения..
И такие, чтобы, например, 4/2 и 10/5 получались  равными друг другу)

И ещё я бы посмотрел на Compile-time rational arithmetic http://en.cppreference.com/w/cpp/numeric/ratio

Да, Вы правы! Но мне не хочется замарачиваться с сокращениями дробей и поиском наименьшего общего знаменателя. Время дорого. Тут главное ООП освоить.

После прочтения вот этого правила, у меня возникли сложности с пониманием: Правило 23: Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса http://www.e-reading.co.uk/chapter.php/1002058/60/Mayers_-_Effektivnoe_ispolzovanie_CPP.html

Получается, что оператор вывода на экран (<<) НЕ должен быть частью класса Relation, так как это НЕ свойство чисел (вывод на экран не относится к классу Relation, так как с точки зрения математики у рациональных чисел есть только свойства сложения, сравнения и т.д.). Следуя правилу, оператор вывода нужно располагать отдельно от класса Relation и даже не friend, а отдельной функцией. Но в том же пространстве имён. А можно ли так делать? C++ позволяет ли создавать свободные операторные функции? Под свободными функциями имеются ввиду функции, которые не являются ни членами-функциями класса, ни функциями-друзьями.
« Последнее редактирование: Февраль 19, 2014, 10:21 от 8Observer8 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Февраль 19, 2014, 10:54 »

Получается, что оператор вывода на экран (<<) НЕ должен быть частью класса Relation, так как это НЕ свойство чисел (вывод на экран не относится к классу Relation, так как с точки зрения математики у рациональных чисел есть только свойства сложения, сравнения и т.д.). Следуя правилу, оператор вывода нужно располагать отдельно от класса Relation и даже не friend, а отдельной функцией. Но в том же пространстве имён. А можно ли так делать? C++ позволяет ли создавать свободные операторные функции? Под свободными функциями имеются ввиду функции, которые не являются ни членами-функциями класса, ни функциями-друзьями.
Можно ли (и как) - откройте какой-нибудь простенький Qt класс (напр QRect) и там посмотрите синтаксис. Форум с таким вопросом беспокоить не стоит.

А так Вы столкнулись с типичным "каноническим" правилом - которое часто доводится до абсурда. Ах, якобы это уже НЕ свойство чисел - да неужели? Кто как не сам класс знает как себя печатать? В действительности же дело в другом. Пример
Код
C++ (Qt)
class Rational {
public:
friend std::ofstream & operator << ( std::ofstream & strm, const Rational & r );
...
}
Беда в том что теперь класс Rational уже не сможет жить без std::ofstream, создается "плохая" зависимость классов.

Однако никто не мешает написать так
Код
C++ (Qt)
class Rational {
public:
template <class stream>
friend stream & operator << ( stream & strm, const Rational & r );
...
}
Но сила "канона" велика, все-таки с ним лучше/практичнее не спорить  Улыбающийся
Записан
8Observer8
Гость
« Ответ #19 : Февраль 20, 2014, 07:07 »

Igors, Спасибо большое!

Можно ли (и как) - откройте какой-нибудь простенький Qt класс (напр QRect) и там посмотрите синтаксис. Форум с таким вопросом беспокоить не стоит.

Вопрос же был такой: C++ позволяет ли создавать свободные операторные функции? Гугл молчит.

Беда в том что теперь класс Rational уже не сможет жить без std::ofstream, создается "плохая" зависимость классов.

Чем плоха эта зависимость? Мы тоже при программировании консольных приложений не можем жить без <iostream>

И ещё вопрос. Как оператор в моём случае написать?

Ошибка: main.cpp:15: error: no match for 'operator<<' (operand types are 'QTextStream' and 'Rational')
     cout << "product = " << product << endl;
                                    ^
Код:
#include <QCoreApplication>
#include <QTextStream>
#include "rational.h"

QTextStream cin(stdin);
QTextStream cout(stdout);

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    // Перемножаем дроби и выводим результат на экран
    Rational a(2, 3), b(1, 2), c(3, 4), product;
    product = a * b * c;
    cout << "product = " << product << endl;
    cout.flush();

    return app.exec();
}
« Последнее редактирование: Февраль 20, 2014, 07:11 от 8Observer8 » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #20 : Февраль 20, 2014, 07:15 »

Вопрос же был такой:
Что же вы так, а поговорить... Улыбающийся

C++ позволяет ли создавать свободные операторные функции? Гугл молчит.
А почему нет, конечно позволяет.
Дружба нужна, только если нужен доступ к закрытым членам.
« Последнее редактирование: Февраль 20, 2014, 07:33 от Old » Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #21 : Февраль 20, 2014, 07:20 »

Вопрос же был такой: C++ позволяет ли создавать свободные операторные функции? Гугл молчит.

можно:
Код:
class Bar
{
public:
Bar(int i = 0) : _i(i) { }
~Bar() { }
int _i;
};

Bar operator+(const Bar& b1, const Bar& b2)
{
Bar result;
result = b1;
result._i += b2._i;
return result;
}

int main(int argc, char *argv[])
{
Bar b1(1);
Bar b2(2);
Bar r = b1 + b2;
return 0;
}


P.S. пока писал, ответили
« Последнее редактирование: Февраль 20, 2014, 07:55 от Johnik » Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #22 : Февраль 20, 2014, 08:24 »

Чем плоха эта зависимость? Мы тоже при программировании консольных приложений не можем жить без <iostream>

Цитата: Гради Буч
Наименее желательной является связность по случайному принципу, когда в одном классе или модуле собираются совершенно независимые абстракции. Для примера можно вообразить класс, соединяющий абстракции собак и космических аппаратов. Наиболее желательной является функциональная связность, при которой все элементы класса или модуля тесно взаимодействуют в достижении определенной цели. Так, например, класс Dog будет функционально связным, если он описывает поведение собаки, всей собаки, и ничего, кроме собаки.
Вам советовали его книгу первым же постом, читали?

И ещё вопрос. Как оператор в моём случае написать?

Ошибка: main.cpp:15: error: no match for 'operator<<' (operand types are 'QTextStream' and 'Rational')
     cout << "product = " << product << endl;
                              ^

Для примера, можно посмотреть как это сделано в исходниках Qt (правда там для QDataStream, для cout надо std::ostream и std::istream):
\src\corelib\tools\qstring.h (и соответствующий .cpp);
Код
C++ (Qt)
#if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &);
Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &);
#endif
 
Записан
8Observer8
Гость
« Ответ #23 : Февраль 20, 2014, 10:14 »

to Old, Johnik
Спасибо за ответы, что операторную функцию можно делать и не дружественной.

Для примера, можно посмотреть как это сделано в исходниках Qt (правда там для QDataStream, для cout надо std::ostream и std::istream):
\src\corelib\tools\qstring.h (и соответствующий .cpp);

Только у меня QTextStream:

Код:
friend QTextStream& operator<<(QTextStream& stream, const Rational& r);

Спасибо! Покапаю исходники Qt.

Скажите, пожалуйста, правильно ли я понял, что единственное для чего нужен полиморфизм - это чтобы писать функции, которые принимают указатель на базовый класс и работают с объектами производных классов (так сказать - для уменьшения дублирования кода)
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #24 : Февраль 20, 2014, 10:31 »

Только у меня QTextStream:

Там было для примера, вот минимум кода:
Код
C++ (Qt)
class Bar
{
public:
Bar(int ii = 0) : i(ii) { }
int i;
};
 
QTextStream& operator<<(QTextStream& stream, const Bar& bar)
{
stream << QString::number(bar.i);
return stream;
}
int main(int argc, char *argv[])
{
Bar b1(1);
 
QString s;
QTextStream out(&s);
out << b1;
return 0;
}

Не надо все воспринимать все буквально, учитесь думать и искать самостоятельно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Февраль 20, 2014, 10:57 »

Скажите, пожалуйста, правильно ли я понял, что единственное для чего нужен полиморфизм - это чтобы писать функции, которые принимают указатель на базовый класс и работают с объектами производных классов (так сказать - для уменьшения дублирования кода)
Единственное или нет - не задумывался. И очень многое придумано "для уменьшения дублирования кода", т.е. это достойная цель. А вообще полиморфизм - одна из самых легких, приятных и полезных вещей в ООП, когда результат/эффект налицо.
Записан
8Observer8
Гость
« Ответ #26 : Февраль 20, 2014, 13:11 »

Спасибо, парни!

Вот такая сейчас ошибка, помогите понять:
Цитировать
error: 'QTextStream& Rational::operator<<(QTextStream&, const Rational&)' must take exactly one argument
 QTextStream &Rational::operator<<(QTextStream &stream, const Rational &r)
                                                                                                               ^
                           

Говорит, что должен быть один аргумент.

main.cpp
Код
C++ (Qt)
#include <QCoreApplication>
#include <QTextStream>
#include "rational.h"
 
QTextStream cin(stdin);
QTextStream cout(stdout);
 
int main(int argc, char *argv[])
{
   QCoreApplication app(argc, argv);
 
   Rational a(2, 3);
   cout << "a = " << a << endl;
   cout.flush();
 
   return app.exec();
}
 

rational.h
Код
C++ (Qt)
#ifndef RATIONAL_H
#define RATIONAL_H
 
#include <QTextStream>
 
namespace RationalStuff {
class Rational;
}
 
class Rational
{
public:
   Rational(int numerator = 0, int denominator = 1);
 
   int numerator() const;
   void setNumerator(const int numerator);
 
   int denominator() const;
   void setDenominator(const int denominator);
 
//    friend const Rational operator*(const Rational& lhs, const Rational& rhs);
//    friend const Rational operator+(const Rational& lhs, const Rational& rhs);
//    friend const Rational operator-(const Rational& lhs, const Rational& rhs);
   friend QTextStream& operator<<(QTextStream& stream, const Rational& r);
 
private:
   int mNumerator;
   int mDenominator;
};
 
#endif // RATIONAL_H
 

rational.cpp
Код
C++ (Qt)
#include "rational.h"
 
Rational::Rational(int numerator, int denominator) :
   mNumerator(numerator),
   mDenominator(denominator)
{
}
 
int Rational::numerator() const
{
   return mNumerator;
}
 
void Rational::setNumerator(const int numerator)
{
   mNumerator = numerator;
}
 
int Rational::denominator() const
{
   return mDenominator;
}
 
void Rational::setDenominator(const int denominator)
{
   mDenominator = denominator;
}
 
QTextStream &Rational::operator<<(QTextStream &stream, const Rational &r)
{
   stream << r.mNumerator << "/" << r.mDenominator;
   return stream;
}
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #27 : Февраль 20, 2014, 13:14 »

Оператор не является членом класса!

rational.cpp
Код
C++ (Qt)
QTextStream &operator<<(QTextStream &stream, const Rational &r)
{
   stream << r.mNumerator << "/" << r.mDenominator;
   return stream;
}
 
Записан
OKTA
Гость
« Ответ #28 : Февраль 20, 2014, 13:16 »

А разве не просто то, что он ждет только один параметр, а не два?))
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #29 : Февраль 20, 2014, 13:18 »

Нет! Old прав. И я точно такой же пример приводил.
Записан
Страниц: 1 [2] 3 4 ... 13   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.314 секунд. Запросов: 23.