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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 14.10.2014, 11:27   #61
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Действительно, очень интересно) Сейчас доработаю и выложу

Плюс у меня еще 1 вопрос напрашивается:
Цитата:
Если есть выбор между функцией-членом (которая имеет доступ не только к закрытым данным класса, но также к его закрытым функциям, перечислениям, определениям типов (typedef) и т. п.) и свободной функцией, не являющейся к тому же другом класса (такие функции не имеют доступа ни к чему из вышеперечисленного), но обеспечивающей ту же функциональность, то напрашивается очевидный вывод: большую инкапсуляцию обеспечивает функция, не являющаяся ни членом, ни другом, потому что она не увеличивает числа функций, которые могут иметь доступ к закрытой секции класса.
Если не делать функцию перегрузки дружественной, то увеличивается число методов, которые имеют доступ к защищенным полям!
Код:
int sec() { return m_sec; }

Последний раз редактировалось Stilet; 18.10.2014 в 11:26.
igoreshka3333 вне форума Ответить с цитированием
Старый 14.10.2014, 13:54   #62
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Цитата:
Сообщение от igoreshka3333 Посмотреть сообщение
Плюс у меня еще 1 вопрос напрашивается:
Если не делать функцию перегрузки дружественной, то увеличивается число методов, которые имеют доступ к защищенным полям!
Код:
int sec() { return m_sec; }
Eсли доступ к внутренним закрытым переменным при печати необходим, то надо делать оператор дружественным, чтобы не плодить лишние методы доступа. Но если есть возможность этого не делать, что нужно следовать правилу. И автор объясняет почему нарушение инкапсуляции это плохо, и почему надо к ней стремиться. Но в классе Time есть в открытом интерфейсе метод для доступа к закрытой переменной "m_sec" и поэтому есть возможность соблюдать правило выше и не нарушать инкапсуляцию (внутренний мир объекта, как я её понимаю)

Последний раз редактировалось 8Observer8; 14.10.2014 в 14:47.
8Observer8 вне форума Ответить с цитированием
Старый 14.10.2014, 17:38   #63
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Ну вот, что у меня вышло:

Код:
Time.h

#ifndef TIME_H
#define TIME_H
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;

class Time
{
private:
    int hour;
    int min;
    int sec;
public:
    int r_hour() const { return hour; }
    int r_min() const { return min; }
    int r_sec() const { return sec; }
    void get_time();
    bool isHour () const { return (hour >= 0 && hour < 24); }
    bool isMin () const { return (min >= 0 && min < 60); }
    bool isSec () const { return (sec >= 0 && sec < 60); }
    Time& operator-- ();
    void sw () const
    {
        cout.fill('0');
        cout.width(2);
    };
};
#endif // TIME_H
Код:
Timer.cpp

#include "time.h"
Time& Time::operator-- ()
{
    if (sec == 0)
    {
        if (min == 0 &&  hour == 0)
        {
            cout << endl;
            system ("pause");
            exit (1);
        }
        if (min == 0 && hour>0)
        {
            min = 60;
            hour--;
        }
        sec = 60;
        min--;
    }
    sec--;
    return *this;
}

//------------------------------------------------------
void Time::get_time ()
{
    while (true)
    {
        cout << "\nEnter the hours: ";
        cin.unsetf(ios::skipws);
        cin >> hour;
        if (isHour () && cin.good() )
        { break; }
        cin.clear(); cin.ignore(10, '\n');
        cerr << "Wrong format!!!";
    }
    cin.clear(); cin.ignore(10, '\n');
    while (true)
    {
        cout << "Enter the minutes: ";
        cin.unsetf(ios::skipws);
        cin >> min;
        if (isMin() && cin.good())
        {  break; }
        cin.clear(); cin.ignore(10, '\n');
        cout << "Wrong format!!!\n";
    }
    cin.clear(); cin.ignore(10, '\n');
    while (true)
    {
        cout << "Enter the seconds: ";
        cin.unsetf(ios::skipws);
        cin >> sec;
        if (isSec() && cin.good())
        {  break; }
        cin.clear(); cin.ignore(10, '\n');
        cout << "Wrong format!!!\n";
    }
}
Код:
main.cpp

#include "time.h"
ostream& operator<< (ostream& stream, Time t)
{
    t.sw();
    cout << t.r_hour();
    cout << " : ";
    t.sw();
    cout << t.r_min();
    cout << " : ";
    t.sw();
    cout << t.r_sec();
    cout << '\r';
    return stream;
}
//--------------------------------------------------------------------
int main ()
{
    Time t;
    cout << "Start the timer: \n";
    t.get_time();
    cout << "\nTimer set: \n\n";
    while (true)
    {
      cout << --t;
      Sleep(1000);
    }
    cout << endl;
    system ("pause");
}

Последний раз редактировалось igoreshka3333; 14.10.2014 в 17:44.
igoreshka3333 вне форума Ответить с цитированием
Старый 15.10.2014, 10:03   #64
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

--------------------------
Когда делаете отдельный файл, то никогда в нём не пишить "использовать std, как глобальное пространство имён":
Код:
using namespace std;
Так как у вас могут возникнуть конфликты имён. Когда вы подключаете файл, в котором есть "using namespace std" то вы с этого момента во всём коде будете иметь это пространство и вероятность конфликта между вашими переменными\функциями и переменными\функциями из std:: повышается

Приучите себя сразу писать std::cout. Так делают все среднички (вроде меня и вас) и профи. В очень простых демо-примера можно написать "using namespace std;". Но я даже в демо-примерах пришу std::

Упражнение. Уберите строку "using namespace std;"



--------------------------
Никогда не встречал таких имён функций:
Код:
int r_hour() const { return hour; }
Не надо стараться быть оригинальным и делать так, как другие не делают. Смотрите, как делают профи. Они делают проще насколько это можно и так как делает большинство средничков и профи:
Код:
int hour() const { return hour; }
Некоторые ещё пишут get:
Код:
int getHour() const { return hour; }
Упражнение. Замените на hour()



--------------------------
В конце функции не нужно ставить точку с запятой:
Код:
void sw () const
    {
        cout.fill('0');
        cout.width(2);
    };


--------------------------
Защищённые переменные необходимо снабжать отличительным признаком. Есть множество вариантов, вот несколько из них:

Код:
private:
    int _hour;
    int _min;
    int _sec;
Код:
private:
    int mHour;
    int mMin;
    int mSec;
Я предпочитаю этот:
Код:
private:
    int m_hour;
    int m_min;
    int m_sec;
Упражнение. Замените имена закрытых переменных класса (m_)



--------------------------

Упражнение. Добавьте в класс конструктор, чтобы пользователь вашего класса мог использовать его так:
Код:
#include <iostream>
#include "Time.h"

int main ()
{
    Time t( 15, 50, 28 );

    std::cout << "\nTimer set: \n\n";
    while (true)
    {
      std::cout << --t;
      Sleep(1000);
    }
    std::cout << std::endl;
    system ("pause");
}
P.S. Выложете исправленный код

Последний раз редактировалось 8Observer8; 15.10.2014 в 10:07.
8Observer8 вне форума Ответить с цитированием
Старый 15.10.2014, 12:15   #65
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Спасибо за советы)
Time.h
Код:
#ifndef TIME_H
#define TIME_H
#include <iostream>
#include <windows.h>
#include <process.h>

class Time
{
private:
    int _hour;
    int _min;
    int _sec;
public:
    Time(int h, int m, int s)
    {_hour = h, _min = m, _sec = s;}
    int hour() const { return _hour; }
    int min() const { return _min; }
    int sec() const { return _sec; }
    void get_time();
    bool isHour () const { return (_hour >= 0 && _hour < 24); }
    bool isMin () const { return (_min >= 0 && _min < 60); }
    bool isSec () const { return (_sec >= 0 && _sec < 60); }
    Time& operator-- ();
    void sw () const
    {
        std::cout.fill('0');
        std::cout.width(2);
    }
};
#endif // TIME_H
Time.cpp
Код:
#include "time.h"
Time& Time::operator-- ()
{
    if (_sec == 0)
    {
        if (_min == 0 && _hour == 0)
        {
            std::cout << std::endl;
            system ("pause");
            exit (1);
        }
        if (_min == 0 && _hour>0)
        {
            _min = 60;
            _hour--;
        }
        _sec = 60;
        _min--;
    }
    _sec--;
    return *this;
}

//------------------------------------------------------
void Time::get_time ()
{
    while (true)
    {
        std::cout << "\nEnter the hours: ";
        std::cin.unsetf(std::ios::skipws);
        std::cin >> _hour;
        if (isHour () && std::cin.good() )
        { break; }
        std::cin.clear(); std::cin.ignore(10, '\n');
        std::cerr << "Wrong format!!!";
    }
    std::cin.clear(); std::cin.ignore(10, '\n');
    while (true)
    {
        std::cout << "Enter the minutes: ";
        std::cin.unsetf(std::ios::skipws);
        std::cin >> _min;
        if (isMin() && std::cin.good())
        {  break; }
        std::cin.clear(); std::cin.ignore(10, '\n');
        std::cerr << "Wrong format!!!\n";
    }
    std::cin.clear(); std::cin.ignore(10, '\n');
    while (true)
    {
        std::cout << "Enter the seconds: ";
        std::cin.unsetf(std::ios::skipws);
        std::cin >> _sec;
        if (isSec() && std::cin.good())
        {  break; }
        std::cin.clear(); std::cin.ignore(10, '\n');
        std::cerr << "Wrong format!!!\n";
    }
}
main.cpp
Код:
#include "time.h"
std::ostream& operator<< (std::ostream& stream, Time t)
{
    t.sw();
    std::cout << t.hour();
    std::cout << " : ";
    t.sw();
    std::cout << t.min();
    std::cout << " : ";
    t.sw();
    std::cout << t.sec();
    std::cout << '\r';
    return stream;
}
//--------------------------------------------------------------------
int main ()
{
    Time t;
    std::cout << "Start the timer: \n";
    t.get_time();
    std::cout << "\nTimer set: \n\n";
    while (true)
    {
      std::cout << --t;
      Sleep(1000);
    }
    std::cout << std::endl;
    system ("pause");
}
igoreshka3333 вне форума Ответить с цитированием
Старый 15.10.2014, 13:07   #66
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Хорошо! Оставлю тут памятку: конструкторы, сеттеры. Позже к ним вернёмся

Теперь выполните такое упражнение (перед выполнением упражнения прочитайте параграф об операторных функциях ниже). Пусть пользователь вашего класса имеет возможность использовать не только префиксный декремент, но и постфиксный:

Код:
int main ()
{
    Time t;
    std::cout << "Start the timer: \n";
    t.get_time();
    std::cout << "\nTimer set: \n\n";
    while (true)
    {
      std::cout << t--;
      Sleep(1000);
    }
    std::cout << std::endl;
    system ("pause");
}
P.S Выложете код только оператора постфикного декремента






8Observer8 вне форума Ответить с цитированием
Старый 15.10.2014, 13:08   #67
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию


8Observer8 вне форума Ответить с цитированием
Старый 16.10.2014, 01:23   #68
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Рекомендую вместо Builder

Установка Qt на Windows

Переходим по ссылке: http://qt-project.org/downloads

Нажимаем кнопку “Show downloads”

Выбираем “Qt 5.3.2 for Windows 32-bit (MinGW 4.8.2, OpenGL, 737 MB)”

Запускаем скаченный файл и следуем инструкции установки

Запуск консольного приложения

Запускаем Qt Creator

Если у вас Qt Creator на русском, то переключите его на английский по этой инструкции:

Переключение Qt на английский

В меню выбираем: “Инструменты” -> “Параметры…”

В окне “Параметры” слева выбираем “Среда” -> открываем вкладку “Основные” -> выбираем в выпадающем списке “English” -> нажимаем кнопку “OK” -> перезапускаем Qt Creator

Запуск консольного приложения (продолжение)

Создадим новый проект. Для этого в меню Qt Creator’а выбираем “File” -> “New File or Project…”

В разделе “Projects” выбираем “Other Project” -> во второй колонке выбираем “Empty Qt Project” -> нажимаем кнопку “Choose…”

В поле “Name” пишем: HelloWorld -> нажимаем кнопку “Browse…” и указываем путь, где будет создан наш проект -> нажимаем два раза “Next” -> нажимаем кнопку “Finish”

Нажимаем правой кнопкой мыши по названию проекта (на панели слева) -> выбираем “Add New…” -> в первом разделе выбираем “C++” -> во втором разделе выбираем “C++ Source File” -> нажимаем кнопку “Choose…” -> водим имя: main -> нажимаем кнопку “Next” -> нажимаем кнопку “Finish”

Отрываем файл HelloWorld.pro и добавляем в него строку: CONFIG += console

Теперь файл HelloWorld.pro выглядит так:

HelloWorld.pro
Код:
CONFIG += console
 
SOURCES += \
    main.cpp
Вставляем в файл main.cpp следующий код:

main.cpp
Код:
#include <iostream>
 
int main()
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}
Запускаем приложение. Для этого нажимаем зелёный треугольник слева внизу (или Ctrl+R)

Примечание. Чтобы программа запустилась в отдельном терминальном окне необходимо на панели слева нажать кнопку “Projects” -> в открывшемся окне, нажать кнопку “Run” -> найти и поставить галочку “Run in terminal” -> нажать кнопку “Edit” (чтобы вернуться к файлам проекта)

Есть ещё замечания к классу Time, но сначала покажите операторную функцию для постфикного декремента

Последний раз редактировалось Stilet; 18.10.2014 в 11:28.
8Observer8 вне форума Ответить с цитированием
Старый 16.10.2014, 11:25   #69
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Цитата:
Есть ещё замечания к классу Time
Возможно вы имеете ввиду дополнительный конструктор, который задает значение по умолчанию?
Насчет постфиксной декрементации усек!
Вот, собственно:

Time.h
Код:
#ifndef TIME_H
#define TIME_H
#include <iostream>
#include <windows.h>
#include <process.h>
class Time
{
private:
    int _hour;
    int _min;
    int _sec;
public:
    Time(int h, int m, int s)
    {_hour = h, _min = m, _sec = s;}
    Time ()
    {_hour = 0; _min = 0; _sec = 0;}
    int hour() const { return _hour; }
    int min() const { return _min; }
    int sec() const { return _sec; }
    void get_time();
    bool isHour () const { return (_hour >= 0 && _hour < 24); }
    bool isMin () const { return (_min >= 0 && _min < 60); }
    bool isSec () const { return (_sec >= 0 && _sec < 60); }
    Time& operator--();
    Time operator--( int );
    void sw () const
    {
        std::cout.fill('0');
        std::cout.width(2);
    }
    void tick();
};
#endif // TIME_H
Time.cpp

Код:
#include "Time.h"
void Time::tick()
{
    if (_sec == 0)
    {
        if (_min == 0 && _hour == 0)
        {
            std::cout << std::endl;
            system ("pause");
            exit (1);
        }
        if (_min == 0 && _hour>0)
        {
            _min = 60;
            _hour--;
        }
        _sec = 60;
        _min--;
    }
    _sec--;
}
//------------------------------------------------------
Time& Time::operator-- ()
{
    tick();
    return *this;
}
//------------------------------------------------------
Time Time::operator--( int )
{
    Time t = *this;
    tick();
    return t;
}
//------------------------------------------------------
void Time::get_time ()
{
    while (true)
    {
        std::cout << "\nEnter the hours: ";
        std::cin.unsetf(std::ios::skipws);
        std::cin >> _hour;
        if (isHour () && std::cin.good() )
        { break; }
        std::cin.clear(); std::cin.ignore(10, '\n');
        std::cerr << "Wrong format!!!";
    }
    std::cin.clear(); std::cin.ignore(10, '\n');
    while (true)
    {
        std::cout << "Enter the minutes: ";
        std::cin.unsetf(std::ios::skipws);
        std::cin >> _min;
        if (isMin() && std::cin.good())
        {  break; }
        std::cin.clear(); std::cin.ignore(10, '\n');
        std::cerr << "Wrong format!!!\n";
    }
    std::cin.clear(); std::cin.ignore(10, '\n');
    while (true)
    {
        std::cout << "Enter the seconds: ";
        std::cin.unsetf(std::ios::skipws);
        std::cin >> _sec;
        if (isSec() && std::cin.good())
        {  break; }
        std::cin.clear(); std::cin.ignore(10, '\n');
        std::cerr << "Wrong format!!!\n";
    }
}
main.cpp

Код:
#include "Time.h"
std::ostream& operator<< (std::ostream& stream, Time t)
{
    t.sw();
    std::cout << t.hour();
    std::cout << " : ";
    t.sw();
    std::cout << t.min();
    std::cout << " : ";
    t.sw();
    std::cout << t.sec();
    std::cout << '\r';
    return stream;
}
//--------------------------------------------------------------------
int main ()
{
    Time t;
    std::cout << "Start the timer: \n";
    t.get_time();
    std::cout << "\nTimer set: \n\n";
    while (true)
    {
      std::cout << t--;
      Sleep(1000);
    }
    std::cout << std::endl;
    system ("pause");
}
Вопрос:
Код:
Time Time::operator--( int )
{
    Time t = *this;
    tick();
    return t;
}
Метод принимает в качестве аргумента ИНТ как фейковый что б компилятор не ругался насчет множественного обьявления одной и той же функции?

Последний раз редактировалось Stilet; 18.10.2014 в 11:28.
igoreshka3333 вне форума Ответить с цитированием
Старый 16.10.2014, 11:51   #70
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Эти два конструктора можно объединить в один, тогда число строк кода уменьшится:
Код:
Time(int h, int m, int s)
    {_hour = h, _min = m, _sec = s;}
    Time ()
    {_hour = 0; _min = 0; _sec = 0;}
Вот так:
Код:
    Time(int h = 0, int m = 0, int s = 0)
    {_hour = h, _min = m, _sec = s;}
Вам теперь будет интересно это правило прочитать про список инициализации (только там в коде ошибки есть, лучше, конечно, книжку скачать) Правило 4: Прежде чем использовать объекты, убедитесь, что они инициализированы

Ошибку в коде правила заметил такую: двоеточие ставится перед каждой переменной, а нужно написать его один раз, как в примере:
Код:
    Time(int h = 0, int m = 0, int s = 0) :
        _hour( h ),  _min( m ), _sec( s ) {}
Списки инициализации пишут все среднички и профи, так что привыкайте

В вашем коде есть недостаток. Вот допустим пользователь вашего класса создал объект класса Time с помощью конструктора. А в процессе работы захотел изменить время. Короче говоря, чаще всего, там где есть геттеры - есть и сеттеры. Геттеры у вас есть, теперь напишите сеттеры. Если непонятно, то я уточню

После исправлений скопируйте весь код. Ещё подумаем, что можно улучшить

Последний раз редактировалось 8Observer8; 16.10.2014 в 12:35.
8Observer8 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
описать класс в с# volkodinocka Помощь студентам 0 09.11.2013 22:05
Описать класс С# NeoX_2011 Помощь студентам 1 19.03.2012 00:10
C# исправление ошибки. Описать класс, реализующий шестнадцатеричный счетчик PROkaZZZniK Помощь студентам 7 09.02.2012 16:29
Описать класс-родитель и класс-потомок. Delphi 7 Andrew_M Помощь студентам 0 15.01.2011 14:42
Описать класс. Telec Общие вопросы C/C++ 1 30.04.2010 18:43