Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Ghost Writter
52 / 52 / 19
Регистрация: 09.12.2015
Сообщений: 215
1

Локальные переменные или прямое обращение к get-объекта класса?

06.01.2016, 10:04. Просмотров 976. Ответов 33
Метки нет (Все метки)

Собственно, что лучше? Создавать локальные переменные и хранить там значения, полученные из экземпляра или напрямую обращаться к полям объекта?

Например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Array::operator +(Array value)
{
    int sizeFirst = getSize();
    int sizeSecond = value.getSize();
 
    if(sizeFirst > sizeSecond)
    {
 
    }
    else if(sizeFirst < sizeSecond)
    {
 
    }
    else
    {
 
    }
}
или

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Array::operator +(Array value)
{
    if(getSize() > value.getSize())
    {
 
    }
    else if(getSize() < value.getSize())
    {
 
    }
    else
    {
 
    }
}
Ну, и почему? Склоняюсь к первому варианту, но, возможно, что разницы не будет и оптимальным вариантом будет второй пример.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.01.2016, 10:04
Ответы с готовыми решениями:

Переменные или обращение к методам
Здравствуйте, хотелось бы узнать, что использовать лучше (и/или менее &quot;памятезатратно&quot;) - обращение...

Считывание из файла значений в переменные объекта класса
Предположим, что есть некий класс const int n=10; class Example { private: int id,number;...

Глобальные и локальные переменные: что лучше (или что для чего и в чем конкретная разница)?
Что лучше (или как надо (или что для чего и в чем конкретная разница)): 1. // объявление в...

Прямое обращение к памяти
Доброго всем времени суток. Товарищи, помогите пожалуйста найти литературу для компилятора DJGPP....

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

33
Apostol584
244 / 150 / 118
Регистрация: 26.11.2012
Сообщений: 376
Завершенные тесты: 2
06.01.2016, 10:11 2
Первый вариант лучше, если в функции getSize() есть вычисления, то они будут производится каждый раз при вызове функции, также вызов функции требует времени, поэтому лучше записать эти значения в переменные.
0
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
06.01.2016, 10:14 3
Зачем тут, вообще, get-ы? У тебя оператор член класса, он и без get-ов имеет доступ к приватным данным класса.
0
Croessmah
++Ͻ
15816 / 8951 / 1719
Регистрация: 27.09.2012
Сообщений: 21,994
Записей в блоге: 2
Завершенные тесты: 2
06.01.2016, 10:15 4
Цитата Сообщение от Apostol584 Посмотреть сообщение
то они будут производится каждый раз при вызове функции, также вызов функции требует времени
Если там всё тривиально, то нормальный компилятор всё это дело встроит и никаких вызовов не будет.

nord_v, зависит от логики getSize.
1
06.01.2016, 10:15
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
06.01.2016, 10:26 5
Цитата Сообщение от Croessmah Посмотреть сообщение
nord_v, зависит от логики getSize.
Не усложняй. На 100 процентов уверен, что, для кода, который привёл ТС (и то, что осталось за кадром у него), get-ы не нужны.

Добавлено через 5 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Array::operator +(Array value)
{
    if(size > value.size)
    {
 
    }
    else if(size < value.size)
    {
 
    }
    else
    {
 
    }
}
0
Croessmah
06.01.2016, 10:28
  #6

Не по теме:

Цитата Сообщение от nord_v Посмотреть сообщение
Не усложняй.
Не упрощай! Контекст неизвестен.

0
nord_v
06.01.2016, 10:30
  #7

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
Контекст неизвестен
Ясновиденье включи.:)

0
Melg
541 / 162 / 79
Регистрация: 23.09.2013
Сообщений: 316
06.01.2016, 11:21 8
Ghost Writter, С Новым годом! В первую очередь, задаваясь вопросом как лучше делать, следует исходить из того, какую цель Вы преследуете. В знаменитой книге Мартина Фаулера - Рефакторинг, присутствуют оба рефакторинга, как "Замена переменной вызовом метода", подробнее с примером:
https://refactoring.guru/ru/replace-temp-with-query , так и "Извлечение переменной" подробнее с примером: https://refactoring.guru/ru/extract-variable Конечно оба этих рефакторинга чаще всего применяются в более сложных ситуациях (когда становится очевидной польза сокрытия информации) В первом случае - за вызовом метода скрывается некоторое вычисление, во втором случае - результат выражения скрывается за переменной имя которой поясняет суть выражения.

Переходя применительно к Вашему случаю следует отметить следующее.
Непосредственно по поставленному вопросу:
1) Читаемость: Вы создаете не константные локальные переменные, которые (теоретически) могут быть изменены, а значит при последующем чтении реализации данного метода придется думать о том, не произошел ли этот досадный казус. Как минимум следовало сделать их константными

2) Run time производительность: Если сложность вычисления размера вашего контейнера оценивается как O(1) - т.е. имеет константную сложность, то в принципе, по сравнению с операциями копирования элементов( В общем случае её сложность O(N) - линейная относительно числа элементов) - наличие 2х или 4х или даже 8х вызовов метода getSize() не приведет к явной потере производительности. В любом случае вопрос производительности во-первых решается на уровне оценки сложности алгоритма (просто так вызывать size-ы у листов - не лучшая идея) - а далее - если производительность остается под вопросом - выясняется путем измерения производительности и оценки наиболее узких мест программы, на которых тратится большинство циклов работы. Преждевременная оптимизация есть зло. Но преждевременная пессимизация зло так-же.

3) Алгоритм: Не совсем понятна суть алгоритма, который вы собираетесь применять. Почему для сложения двух массивов требуется 3 разные пути выполнения для случаев разного соотношения их размеров? С методологической точки зрения это не верно. Я исхожу из следующего:
Если Вы подразумеваете семантику типа массив {1, 4, 7} + {2, 5} => {1, 4, 7, 2, 5} - то в таком случае нас интересует просто сумма размеров.
Если Вы подразумеваете семантику типа {1, 2, 3} + {3, 2, 1,} => {4, 4, 4} - то в этом случае обрабатываемые диапазоны должны быть одинакового размера в любом случае (как пример из стандартной библиотеки: http://www.cplusplus.com/reference/algorithm/transform/ , явное указание ограничения : first2 Input iterator to the initial position of the second range. The range includes as many elements as [first1,last1).) - Если переводить из понятия итераторов на понятие размера - пользователь должен был бы гарантировать равный размер массивов.

Подводя промежуточный итог, я бы предпочел увидеть код типа:
C++
1
auto minimal = std::min(getSize(), value.getSize());
вообще без ветвления в принципе.
Если это не возможно, а проблемы производительности нас не волнуют, тогда более чистую версию:
C++
1
2
3
4
5
6
7
  if (getSize() > value.getSize()) {
     // first
  } else if (getSize() < value.getSize()) {
     // second
  } else {
     // third
  }
Либо без вызова методов, а через прямой доступ к полям, но без ввода локальных переменных.
Наконец при явной необходимости явно вводить переменные для каких-то целей (должно быть четкое представление зачем они введены),
я бы предпочел четкие имена у данных переменных в сочетании с константностью:

C++
1
2
3
4
5
6
7
8
9
10
11
void Array::operator+(Array oth) {
  const auto my_size = getSize();
  const auto other_size = oth.getSize();
  if (my_size > other_size) {
    // first
  } else if (my_size < other_size) {
    // second
  } else {
    // third
  }
}
Теперь, что касается моих заметок по Вашему коду:
1) В любом случае следовало передавать складываемый контейнер по константной ссылке, сейчас происходит полное копирование value при вызове метода, а правильнее:
C++
1
void Array::operator+(const Array &oth) {
2) В любом случае при реализации оператора + стоит возвращать не void, а ссылку на объект того же типа, поскольку ваш код не поддерживает сценария
C++
1
2
Array a, b, c; // допустим инициализированы значениями
 a + b + c; // выдаст ошибку компиляции, поскольку результат a + b = void
Правильнее:
C++
1
Array & Array::operator+(const Array &oth) {
3) Ваш код нарушает семантику сложения, принятую для value типов:
C++
1
int c = a + b;
При использовании вашего кода пришлось бы писать что-то типа:
C++
1
2
3
Array a, b, c;
a + b;
a + c;
Для int такие операции выглядят как нонсенс.
Кроме того, операция сложения НЕ изменяет текущие складываемые значения, она ПОРОЖДАЕТ новое значение как сумму складываемых.
Каноничная форма сложения выглядела бы как свободная friend(при необходимости) функция с сигнатурой:
C++
1
Array operator+(const Array &lhs, const Array &rhs);
Для примера можете взглянуть на функции сложения из стандартной библиотеки, для типа строк:
http://www.cplusplus.com/reference/string/string/

4) В общем случае, если сложение двух массивов (статических) производится по правилам {1, 2, 3} + {4 , 5} => {1, 2, 3, 4, 5} то размер нового массива
нужно вычислять статически на этапе компиляции.

5) Ни для статического массива, ни для его динамической версии не определяется оператор сложения, это связано с теорией типов. Ни для array ни для vector:
http://ru.cppreference.com/w/cpp/container/array
http://www.cplusplus.com/reference/vector/vector/
Оператор + не определен. Кроме того сами элементы вектора или массива не обязаны реализовывать оператор +.

При необходимости каким-либо образом воздействовать на элементы, используются отдельные алгоритмы, работающие на итераторах, как уже приведенный мною transform:
http://www.cplusplus.com/reference/algorithm/transform/

Подробнее по поводу регулярных типов читайте в книге от создателя stl:
Александр Степанов, Пол Мак-Джоунс - Начала программирования.
3
Renji
2513 / 1719 / 515
Регистрация: 05.06.2014
Сообщений: 4,981
06.01.2016, 11:31 9
Цитата Сообщение от Ghost Writter Посмотреть сообщение
Собственно, что лучше? Создавать локальные переменные и хранить там значения, полученные из экземпляра или напрямую обращаться к полям объекта?
Если обращаться напрямую, могут возникнуть не очевидные проблемы с оптимизацией кода.
C++
1
2
3
4
5
6
7
8
9
void Array::operator +(const Array&value)
{
    //умный компилятор читает поля объекта и сохраняет в регистры процессора. Пригодится
    if(getSize()>value.getSize())
    {
        setSize(getSize()+1);
        //а теперь Угадайка - изменилось value.getSize() или нет?
        //может компилятор доверять регистровой копии value.getSize() или нет?
        //Подсказка - вдруг этот оператор вызвали в форме A+A и &value==this?
0
Nick Alte
Эксперт С++
1655 / 1027 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
06.01.2016, 11:57 10
Цитата Сообщение от Renji Посмотреть сообщение
Если обращаться напрямую, могут возникнуть не очевидные проблемы с оптимизацией кода.
Такие утверждения стоило бы иллюстрировать ассемблерным выхлопом, подтверждающим факт возникновения проблем.

Цитата Сообщение от Ghost Writter Посмотреть сообщение
Собственно, что лучше?
Думаю, лучше непосредственно обращаться к get-методам. Получается более очевидный код, менее завязанный на интимное знакомство с внутренностями класса, что облегчает внесение изменений, рефакторинг и всё такое. Ну а оптимизация - самое последнее, чем стоит заморачиваться в этом вопросе.
0
Renji
2513 / 1719 / 515
Регистрация: 05.06.2014
Сообщений: 4,981
06.01.2016, 12:27 11
Цитата Сообщение от Nick Alte Посмотреть сообщение
Такие утверждения стоило бы иллюстрировать ассемблерным выхлопом, подтверждающим факт возникновения проблем.
Ради бога. test.h
C++
1
2
3
4
5
6
7
8
struct test
{
    int x;
 
    test():x(0){}
    int direct_method(const test&value);
    int local_variable_method(const test&value);
};
test.cpp (отдельно от майна, дабы компилятор все не заинлайнил)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include"test.h"
int test::direct_method(const test &value)
{
    x+=value.x;
    return value.x;
}
 
int test::local_variable_method(const test &value)
{
    int temp=value.x;
    x+=temp;
    return temp;
}
Выхлоп для direct_method:
Assembler
1
2
3
4
5
6
0x8048780  <+0x0000>         mov    0x8(%esp),%eax
0x8048784  <+0x0004>         mov    0x4(%esp),%edx
0x8048788  <+0x0008>         mov    (%eax),%ecx
0x804878a  <+0x000a>         add    %ecx,(%edx)
0x804878c  <+0x000c>         mov    (%eax),%eax
0x804878e  <+0x000e>         ret
Выхлоп для local_variable_method:
Assembler
1
2
3
4
5
0x8048790  <+0x0000>         mov    0x8(%esp),%eax
0x8048794  <+0x0004>         mov    0x4(%esp),%edx
0x8048798  <+0x0008>         mov    (%eax),%eax
0x804879a  <+0x000a>         add    %eax,(%edx)
0x804879c  <+0x000c>         ret
Как несложно заметить, local_variable_method на одну команду короче. Хотя, казалось бы, код функций практически эквивалентен, а С++ код local_variable_method вообще длиннее.
0
Nick Alte
Эксперт С++
1655 / 1027 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
06.01.2016, 12:54 12
Цитата Сообщение от Renji Посмотреть сообщение
Как несложно заметить, local_variable_method на одну команду короче.
А вот интересно, что и результаты у этих методов разные. Ассемблерная реализация local_variable_method не сохраняет результат сложения в this->x. Потому и нету одной команды.
0
Renji
2513 / 1719 / 515
Регистрация: 05.06.2014
Сообщений: 4,981
06.01.2016, 13:30 13
Цитата Сообщение от Nick Alte Посмотреть сообщение
А вот интересно, что и результаты у этих методов разные. Ассемблерная реализация local_variable_method не сохраняет результат сложения в this->x. Потому и нету одной команды.
Тестовый запуск показывает что this->x меняется вполне корректно. Чему я вижу два объяснения - или дизассемблер QtCreator пишет аргументы add в порядке "источник, приемник", или он просто глючит.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include"test.h"
 
using namespace std;
 
int main()
{
    test t,t1;
    t.x=1;
    t1.x=2;
    cout<<t.direct_method(t1)<<endl;
    cout<<t.local_variable_method(t1)<<endl;
    cout<<t.x<<endl;
    cout<<t1.x<<endl;
    return 0;
}
Добавлено через 6 минут
Цитата Сообщение от Renji Посмотреть сообщение
Чему я вижу два объяснения - или дизассемблер QtCreator пишет аргументы add в порядке "источник, приемник"
UPD Ну да, так и есть, гугление показывает что gcc используемый в моем QtCreator придерживается Source-Destination Ordering.
0
Nick Alte
Эксперт С++
1655 / 1027 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
06.01.2016, 13:38 14
Ну в таком случае, возвращается не сумма, а слагаемое. Что мы, оказывается, видим и в исходном методе. Прозреваю, что если в local_variable_method возвращать всё же сумму, то и ассемблерный выхлоп окажется неотличим.
0
Renji
2513 / 1719 / 515
Регистрация: 05.06.2014
Сообщений: 4,981
06.01.2016, 14:03 15
Цитата Сообщение от Nick Alte Посмотреть сообщение
Ну в таком случае, возвращается не сумма, а слагаемое. Что мы, оказывается, видим и в исходном методе. Прозреваю, что если в local_variable_method возвращать всё же сумму, то и ассемблерный выхлоп окажется неотличим.
Так и direct_method возвращает слагаемое (value.x). Здесь фокус не в возвращении суммы, а в возможности конструкции вида some_value.direct_method(some_value). При этом получается что аргумент direct_method - константа, но эта константа изменяется внутри метода (так как доступна через this без модификатора const). Компилятор держит этот изврат в уме и добавляет дополнительную команду для корректной работы с извращенцами. Понятно, что в 99% случаев никто такую хрень писать не станет, но формально то все корректно.
2
Nick Alte
Эксперт С++
1655 / 1027 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
06.01.2016, 16:28 16
Цитата Сообщение от Renji Посмотреть сообщение
Так и direct_method возвращает слагаемое
Теперь разобрался. По сути согласен, но исходную формулировку всё же не одобряю. Там дело не в оптимизации, а именно в корректности кода (то есть, смысл обеих функций выглядит идентичным, но имеется важное незаметное на первый взгляд различие, что и выливается в лишнюю команду).
0
Ghost Writter
52 / 52 / 19
Регистрация: 09.12.2015
Сообщений: 215
09.01.2016, 08:09  [ТС] 17
Melg, ну, вообще. Задание такое:

Задание
1) Создать поток расчёта сложной функции по случайным входным данным.
2) Создать поток вывода результатов расчёта через каждые 3 сек.
3) Синхронизировать потоки.
4) Реализовать операции полного останова потоков, перевода потоков в режим ожидания, запуска потоков.
Дополнительные требования: - потоки работают бесконечно.

Сам код у меня получился:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//array.h
 
#ifndef ARRAY_H
#define ARRAY_H
 
 
class Array
{
public:
    Array();
    ~Array();
    void setArray(int *, int);
    int *getArray();
    int getSize();
    void clearArray();
    void inputArray();
    void printArray();
    void operator +(Array);
    void createArray();     //не нужно создавать отдельный элемент суммирования, трата времени
private:
    int *array;
    int size;
};
 
#endif // ARRAY_H
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//array.cpp
 
#include "stdlib.h"
#include "array.h"
#include "iostream"
#include <ctime>
 
using std::wcout;
using std::cout;
using std::cin;
using std::endl;
 
Array::Array()
{
    array = new int[0];
    size = 0;
}
 
Array::~Array()
{
    if(array)
        delete[] array;
}
 
void Array::setArray(int *_array, int _size)
{
    if(_size <= 0)
    {
        wcout << L"Неверный размер массива!" << endl;
        return;
    }
 
//    int *newArray = new int[_size];
 
//    for(int i = 0; i < _size; i++)
//        newArray[i] = _array[i];
 
    if(getSize() != 0)
        clearArray();
 
    array = _array;
    size = _size;
}
 
int *Array::getArray()
{
    return array;
}
 
int Array::getSize()
{
    return size;
}
 
void Array::clearArray()
{
    delete array;
    size = 0;
}
 
void Array::inputArray()
{
    wcout << L"Введите количество элементов: " << endl;
 
    int _size;
    bool isCorrect = false;
 
    while(!isCorrect)
    {
        cin >> _size;
 
        if(_size > 0)
            isCorrect = !isCorrect;
        else
            wcout << L"Неверный размер!" << endl;
    }
 
    wcout << L"Введите " << _size << L" элемент(ов)" << endl;
 
    int *newArray = new int[_size];
 
    for(int i = 0; i < _size; i++)
        cin >> newArray[i];
 
    setArray(newArray, _size);
//    printArray();
}
 
void Array::printArray()
{
    int _size = getSize();
 
    if(_size <= 0)
    {
        wcout << L"Массив не инициализован!" << endl;
        return;
    }
 
    //wcout << L"Вывод массива: " << endl;
    int *_Array = getArray();
 
    for(int i = 0; i < _size; i++)
    {
        cout << _Array[i] << "\t";
    }
 
    cout << endl;
    //wcout << L"Всего элементов " << _size << endl;
}
 
void Array::operator +(Array value)
{
    int sizeFirst = getSize();
    int *arrayFirst = getArray();
 
    int sizeSecond = value.getSize();
    int *arraySecond = value.getArray();
 
    if(sizeFirst == 0 && sizeSecond > 0)
    {
        setArray(arraySecond, sizeSecond);
    }
    else if(sizeFirst <= sizeSecond)
    {
        int *newLongArray = new int[sizeSecond];
 
        for(int i = 0; i < sizeFirst; i++)
            newLongArray[i] = arrayFirst[i] + arraySecond[i];
 
        for(int i = sizeFirst; i < sizeSecond; i++)
            newLongArray[i] = arraySecond[i];
 
        setArray(newLongArray, sizeSecond);
    }
    else if(sizeFirst > sizeSecond)
    {
        for(int i = 0; i < sizeSecond; i++)
            arrayFirst[i] += arraySecond[i];
    }
}
 
void Array::createArray()
{
    int _size = rand() % 10 + 1;
    int *_array = new int[_size];
 
    for(int i = 0; i < _size; i++)
    {
        _array[i] = rand() % 100;
    }
    setArray(_array, _size);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//main.cpp
 
/*
 
1) Создать поток расчёта сложной функции по случайным входным данным.
2) Создать поток вывода результатов расчёта через каждые 3 сек.
3) Синхронизировать потоки.
4) Реализовать операции полного останова потоков, перевода потоков в режим ожидания, запуска потоков.
Дополнительные требования: - потоки работают бесконечно
 
*/
 
#include <iostream>
#include <windows.h>
#include <time.h>
#include "array.h"
 
#define sec 1000
 
using namespace std;
 
HANDLE hThreadFirst, hThreadSecond, hThreadThird, hEvent;
 
struct LIFO
{
    Array *array;
    LIFO *nextPtr;
};
 
typedef LIFO STACKNODE;
typedef STACKNODE *STACKNODEPTR;
 
STACKNODEPTR stuck = NULL;
 
bool isThreadEnable, isThreadPause;
 
void push(Array *value)
{
    STACKNODEPTR newPtr = new STACKNODE;
 
    newPtr->array = value;
    newPtr->nextPtr = stuck;
    stuck = newPtr;
}
 
void pop()
{
    STACKNODEPTR tempPtr;
 
    tempPtr = stuck;
    stuck = stuck->nextPtr;
    tempPtr->array->printArray();
    tempPtr->array->~Array();
    delete tempPtr;
}
 
void out(STACKNODEPTR currentPtr)
{
    while(currentPtr != NULL)
    {
        currentPtr->array->printArray();
        currentPtr = currentPtr->nextPtr;
    }
}
 
void threadFirst(void *)
{
    while(isThreadEnable)
    {
        DWORD isPause = WaitForSingleObject(hEvent, 0);
 
        Sleep(sec/300);
        if(isPause != WAIT_OBJECT_0)
        {
            Sleep(sec / 130);
            Array *newArray = new Array;
 
            newArray->createArray();
            push(newArray);
        }
    }
}
 
void threadSecond(void *)
{
    while(isThreadEnable)
    {
        WaitForSingleObject(hThreadFirst, sec * 3);
 
        DWORD isPause = WaitForSingleObject(hEvent, 0);
 
        if(isPause != WAIT_OBJECT_0)
        {
            wcout << L"-----------------------------------------------------" << endl;
            while(stuck != NULL)
            {
                pop();
            }
       }
    }
}
 
int main()
{
    setlocale(LC_ALL, "rus");
    srand(time(NULL));
    isThreadEnable = true;
    isThreadPause = false;
 
    hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
 
    wcout << L"0. Создание потоков" << endl
          << L"1. Пауза/Запуск" << endl
          << L"-1. Выход из потоков" << endl;
 
    while(1)
    {
        int item;
        cin >> item;
 
        if(item > 0)
        {
            isThreadPause = !isThreadPause;
 
            if(isThreadPause)
            {
                SetEvent(hEvent);
                wcout << L"Внимание! Пауза!" << endl;
            }
            else
                ResetEvent(hEvent);
        }
        else if(item < 0)
        {
            isThreadEnable = false;
 
            WaitForSingleObject(hThreadSecond, sec);
            wcout << L"Из потоков вышли успешно!" << endl;
        }
        else if(item == 0)
        {
            isThreadEnable = false;
 
            WaitForSingleObject(hThreadSecond, sec);
 
            CloseHandle(hThreadFirst);
            CloseHandle(hThreadSecond);
 
            hThreadFirst = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadFirst, NULL, 0, NULL);
            hThreadSecond = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadSecond, NULL, 0, NULL);
 
            isThreadEnable = true;
            isThreadPause = false;
        }
    }
 
    return 0;
}
В общем, да. Я понял где у меня ошибки. Изначально хотел просто что-то вроде Array a += Array b; Но в процессе изменил решение, но метод оставил для наглядности, может еще что-то подскажете.

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

Это мой первый опыт написания класса. Насчет getSize() или getArray(). Как минимум в двух книгах по программированию читал то, что необходимо использовать именно такой подход. Он более выгоден.

Теперь насчет использование полей или сохранение их в переменную. Недавно на одном комьюнити возник спор, на простую тему как выходить лучше из цикла, использовать для этого булевую переменную или оператор break. Тут код. Как оказалось, это одинаково на ЯА.

Так и здесь хотелось бы узнать. Возможно value.getSize() ничего плохо в себе не несет на уровне ЯА и можно спокойно использовать данный метод.
0
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
09.01.2016, 08:28 18
Цитата Сообщение от Ghost Writter Посмотреть сообщение
Насчет getSize() или getArray(). Как минимум в двух книгах по программированию читал то, что необходимо использовать именно такой подход.
Такой подход используется для доступа к приватным данным класса извне, использовать их в функциях-членах класса - глупо. Функции-члены для того и существуют, чтобы напрямую обращаться к приватным данным класса.
0
Ghost Writter
52 / 52 / 19
Регистрация: 09.12.2015
Сообщений: 215
09.01.2016, 08:37  [ТС] 19
nord_v, Харви М. Дейтел, Пол Дж. Дейтел - Как программировать на C++ - 2008, c.176

Локальные переменные или прямое обращение к get-объекта класса?

Локальные переменные или прямое обращение к get-объекта класса?
0
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
09.01.2016, 08:42 20
Цитата Сообщение от Ghost Writter Посмотреть сообщение
Харви М. Дейтел, Пол Дж. Дейтел - Как программировать на C++ - 2008
И где тут, внутри методов, используются геттеры /сеттеры?
0
09.01.2016, 08:42
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.01.2016, 08:42

Запретить прямое обращение к скрипту, но разрешить обращение через RewriteEngine
основной файл у меня index.php и в нем уже определяется какой файл подключить, к примеру ...

Локальные переменные удаляются при выходе из области видимости или просто становятся невидимыми в новом контексте?
Локальные переменные удаляются при выходе из области видимости или просто становятся невидимыми в...

Можно ли реализовать в классе обращение к свойству по индексу и возврат объекта класса?
Всем привет! Возможно зря замахнулся на такую реализацию, но всё же: Допустим, есть класс...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.