С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
1

Замечания/Улучшения для программы (Сборка сортировок)

19.01.2019, 21:22. Показов 837. Ответов 30
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! имеется данный код:
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <ctime>
#include <string>
 
using namespace std;
 
int num;
 
class SortChoice {
 
public:
    SortChoice() {}
    static SortChoice *choice(string, double *);
    double BubleSortIncrease(double) { return 0; }
    double BubleSortDecrease(double) { return 0; }
    double ShakerSortIncrease(double) { return 0; }
    double ShakerSortDecrease(double) { return 0; }
    double ShellSortIncrease(double) { return 0; }
    double ShellSortDecrease(double) { return 0; }
    ~SortChoice() {}
};
 
class BubleSort : public SortChoice {
 
public:
 
    double BubleSortIncrease(double *arr) {
 
        for (int i = 0; i < num; i++) {
 
            for (int j = 1; j < num - i; j++) {
 
                if (arr[j] < arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
 
    double BubleSortDecrease(double *&arr) {
 
        for (int i = 0; i < num; i++) {
 
            for (int j = 1; j < num - i; j++) {
 
                if (arr[j] > arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
};
 
class ShakerSort : public SortChoice {
 
public:
    double ShakerSortIncrease(double *arr) {
 
        for (int i = 0; i < num / 2; i++) {
 
            for (int j = 1; j < num - i; j++) {
 
                if (arr[j] < arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
 
            for (int j = num - i - 1; j > 1 + i; j--) {
 
                if (arr[j] < arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
 
    double ShakerSortDecrease(double *arr) {
 
        for (int i = 0; i < num / 2; i++) {
 
            for (int j = 1; j < num - i - 1; j++) {
 
                if (arr[j] > arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
 
            for (int j = num - i - 1; j > 1 + i; j--) {
 
                if (arr[j] > arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
};
 
class ShellSort : public SortChoice {
 
public:
    double ShellSortIncrease(double *arr) {
 
        int i, j, step;
        int tmp;
 
        for (step = num / 2; step > 0; step /= 2) {
 
            for (i = step; i < num; i++) {
                tmp = arr[i];
 
                for (j = i; j >= step; j -= step) {
 
                    if (tmp < arr[j - step])
                        arr[j] = arr[j - step];
 
                    else
                        break;
                }
 
                arr[j] = tmp;
            }
        }
 
        return *arr;
    }
 
    double ShellSortDecrease(double *arr) {
 
        int i, j, step;
        int tmp;
 
        for (step = num / 2; step > 0; step /= 2) {
 
            for (i = step; i < num; i++) {
                tmp = arr[i];
 
                for (j = i; j >= step; j -= step) {
 
                    if (tmp > arr[j - step])
                        arr[j] = arr[j - step];
 
                    else
                        break;
                }
 
                arr[j] = tmp;
            }
        }
 
        return *arr;
    }
};
 
SortChoice *SortChoice::choice(string symbol, double *Mass) {
 
    char IorD;
 
    if (symbol == "BS") {
 
        BubleSort *ptr = nullptr;
 
        printf("Icrease(I) or Decrease(D)? ");
        cin >> IorD;
 
        while (IorD != 'i' && IorD != 'D' && IorD != 'd' && IorD != 'I') {
 
            printf("Your entered data uncorrect, enter again, please: "); scanf("%c", &IorD);
            printf("\n");
        }
 
        switch (IorD) {
 
        case 'I': { ptr->BubleSortIncrease(Mass); break; }
        case 'i': { ptr->BubleSortIncrease(Mass); break; }
        case 'D': { ptr->BubleSortDecrease(Mass); break; }
        case 'd': { ptr->BubleSortDecrease(Mass); break; }
        }
    }
 
    else if (symbol == "SS") {
 
        ShakerSort *ptr = nullptr;
 
        printf("Icrease(I) or Decrease(D)? "); cin >> IorD;
 
        while (IorD != 'i' && IorD != 'D' && IorD != 'd' && IorD != 'I') {
 
            printf("Your entered data uncorrect, enter again, please: "); scanf("%c", &IorD);
            printf("\n");
        }
 
        switch (IorD) {
 
        case 'I': { ptr->ShakerSortIncrease(Mass); break; }
        case 'i': { ptr->ShakerSortIncrease(Mass); break; }
        case 'D': { ptr->ShakerSortDecrease(Mass); break; }
        case 'd': { ptr->ShakerSortDecrease(Mass); break; }
        }
    }
 
    else if (symbol == "ShS") {
 
        ShellSort *ptr = nullptr;
 
        printf("Icrease(I) or Decrease(D)? "); cin >> IorD;
 
        while (IorD != 'i' && IorD != 'D' && IorD != 'd' && IorD != 'I') {
 
            printf("Your entered data uncorrect, enter again, please: "); scanf("%c", &IorD);
            printf("\n");
        }
 
        switch (IorD) {
 
        case 'I': { ptr->ShellSortIncrease(Mass); break; }
        case 'i': { ptr->ShellSortIncrease(Mass); break; }
        case 'D': { ptr->ShellSortDecrease(Mass); break; }
        case 'd': { ptr->ShellSortDecrease(Mass); break; }
        }
    }
 
    SortChoice *ptr = nullptr;
 
    return ptr;
}
 
void main() {
 
    char symbol;
    string which_sort;
    SortChoice *to;
 
    printf("Can you write, how nums do u want?\n");
    printf("Massive will has "); scanf("%d", &num);
 
    double *Massive = new double[num];
 
    printf("What method of filling do u prefer? Hand(H) or Random(R)? "); scanf("%c", &symbol);
 
    while (symbol != 'H' && symbol != 'R' && symbol != 'r' && symbol != 'h') {
 
        printf("Your entered data uncorrect, enter again, please: "); scanf("%c", &symbol);
        printf("\n");
    }
 
    printf("Your massive: ");
 
    switch (symbol) {
 
    case 'H':
        for (int i = 0; i < num; i++)
            scanf("%lf", &Massive[i]);
        break;
 
    case 'h':
        for (int i = 0; i < num; i++)
            scanf("%lf", &Massive[i]);
        break;
 
    case 'R':
        srand(time(NULL));
 
        for (int i = 0; i < num; i++) {
 
            Massive[i] = rand() % num;
            printf("%8.2lf, ", Massive[i]);
        }
        break;
 
    case 'r':
        srand(time(NULL));
 
        for (int i = 0; i < num; i++) {
 
            Massive[i] = rand() % num;
            printf("%8.2lf, ", Massive[i]);
        }
        break;
    }
 
    printf("\nWhat sorting method do u want to use? BubleSort(BS), ShakerSort(SS), ShellSort(ShS): "); cin >> which_sort;
 
    to->choice(which_sort, Massive);
 
    printf("\nResult after sorting:\n");
 
    for (int i = 0; i < num; i++)
        printf("%8.1lf ", Massive[i]);
 
    printf("\n");
 
    delete[] Massive;
    system("pause");
}
Это не лаба, не диплом, просто для себя решил сделать =). Пожалуйста, если есть какие-нибудь советы по улучшению работы сортировки, или собсна кода, то всегда РАД и ГОТОВ выслушать! (=
Также есть несколько замечаний:
Я вот хотел в switch впихнуть string-переменную, но нет, поэтому решил if'ами пользоваться, но тут снова проблема, после того, как я напишу string-переменную в консоли, то в IorD почему автоматически впихивается \n, если юзать scanf, а если использовать cin >>, то всё нормально. Почему?
Всем спасибо, заранее!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.01.2019, 21:22
Ответы с готовыми решениями:

Конечная точка улучшения программы
Возьмем, что я написал программу. Я уверен, что есть методы, по которым та же задача будет решаться...

Сборка программы для последующего запуска на другом ПК
Добрый день. Написал небольшую игру (змейку) с использованием SFML библиотеки. На моем ПК все...

Книги для улучшения навыков
Посоветуйте какие-нибудь хорошие книги для улучшения навыков. Основы я вроде как уже знаю, и...

Улучшения для среды delhpi
Доброго дня всем друзья! Приятный вопрос. Существуют ли дополнительные надстройки для Delphi,...

30
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
21.01.2019, 15:47 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от eva2326 Посмотреть сообщение
Деструктор итак по дефолту noexcept
Не всегда же.
Цитата Сообщение от eva2326 Посмотреть сообщение
Нет ни одной причины делать деструктор виртуальным,
Если класс не использует полиморфизм (отсутствуют вирт. функции)
Ну, они и могут появится, все предпосылы там есть.
Цитата Сообщение от eva2326 Посмотреть сообщение
Не понятно, чего вы нукаете?
Запрещено?
0
1659 / 488 / 106
Регистрация: 17.05.2015
Сообщений: 1,497
21.01.2019, 16:24 22
Цитата Сообщение от Azazel-San Посмотреть сообщение
Не всегда же.
Что значит "не всегда"?
Всегда, по дефолту.
Нет ни одной причины дополнительно указывать noexcept функции, которая итак noexcept

Цитата Сообщение от Azazel-San Посмотреть сообщение
Ну, они и могут появится, все предпосылы там есть.
Когда появятся, тогда и нужно делать.

Насчет предпосылок: есть предпосылка выбросить все классы,
оставив обычные сишные функции.
0
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
21.01.2019, 21:46  [ТС] 23
Так а как рандомность чисел посекундно сделать без <ctime>? У меня же написан srand(time(0)). Вместо using namespace std постоянно писать std::? В чем, как вы говорите, "сокральный" смысл постоянно писать эту ерунду, если можно отделаться одним подкл. про-ва имён std? Всего-лишь вопрос (=

Добавлено через 1 час 38 минут
Благодарю за советы, вот получившаяся версия:
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#include <iostream>
#include <ctime>
#include <string>
 
class SortChoice {
 
private:
    int num;
 
public:
    SortChoice(int iget) { num = iget; }
 
    static void *choice(std::string, double *);
 
    double BubleSortIncrease(double *arr) {
 
        for (int i = 0; i < num; i++) {
 
            for (int j = 1; j < num - i; j++) {
 
                if (arr[j] < arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
 
    double BubleSortDecrease(double *arr) {
 
        for (int i = 0; i < num; i++) {
 
            for (int j = 1; j < num - i; j++) {
 
                if (arr[j] > arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
 
    double ShakerSortIncrease(double *arr) {
 
        for (int i = 0; i < num / 2; i++) {
 
            for (int j = 1; j < num - i; j++) {
 
                if (arr[j] < arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
 
            for (int j = num - i - 1; j > 1 + i; j--) {
 
                if (arr[j] < arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
 
    double ShakerSortDecrease(double *arr) {
 
        for (int i = 0; i < num / 2; i++) {
 
            for (int j = 1; j < num - i - 1; j++) {
 
                if (arr[j] > arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
 
            for (int j = num - i - 1; j > 1 + i; j--) {
 
                if (arr[j] > arr[j - 1]) {
 
                    double temp = arr[j];
 
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
 
        return *arr;
    }
 
    double ShellSortIncrease(double *arr) {
 
        int i, j, step;
        double tmp;
 
        for (step = num / 2; step > 0; step /= 2) {
 
            for (i = step; i < num; i++) {
                tmp = arr[i];
 
                for (j = i; j >= step; j -= step) {
 
                    if (tmp < arr[j - step])
                        arr[j] = arr[j - step];
 
                    else
                        break;
                }
 
                arr[j] = tmp;
            }
        }
 
        return *arr;
    }
 
    double ShellSortDecrease(double *arr) {
 
        int i, j, step;
        double tmp;
 
        for (step = num / 2; step > 0; step /= 2) {
 
            for (i = step; i < num; i++) {
                tmp = arr[i];
 
                for (j = i; j >= step; j -= step) {
 
                    if (tmp > arr[j - step])
                        arr[j] = arr[j - step];
 
                    else
                        break;
                }
 
                arr[j] = tmp;
            }
        }
 
        return *arr;
    }
 
    ~SortChoice() {}
};
 
void *SortChoice::choice(std::string symbol, double *Mass) {
 
    char IorD;
    SortChoice *ptr = nullptr;
 
    if (symbol == "BS") {
 
        std::cout << "Icrease(I) or Decrease(D)? ";
        std::cin >> IorD;
 
        while (IorD != 'i' && IorD != 'D' && IorD != 'd' && IorD != 'I') {
 
            std::cout << "Your entered data uncorrect, enter again, please: ";
            std::cin >> IorD;
        }
 
        switch (IorD) {
 
        case 'I': { ptr->BubleSortIncrease(Mass); break; }
        case 'i': { ptr->BubleSortIncrease(Mass); break; }
        case 'D': { ptr->BubleSortDecrease(Mass); break; }
        case 'd': { ptr->BubleSortDecrease(Mass); break; }
        }
    }
 
    else if (symbol == "SS") {
 
        std::cout << "Icrease(I) or Decrease(D)? ";
        std::cin >> IorD;
 
        while (IorD != 'i' && IorD != 'D' && IorD != 'd' && IorD != 'I') {
 
            std::cout << "Your entered data uncorrect, enter again, please: ";
            std::cin >> IorD;
        }
 
        switch (IorD) {
 
        case 'I': { ptr->ShakerSortIncrease(Mass); break; }
        case 'i': { ptr->ShakerSortIncrease(Mass); break; }
        case 'D': { ptr->ShakerSortDecrease(Mass); break; }
        case 'd': { ptr->ShakerSortDecrease(Mass); break; }
        }
    }
 
    else if (symbol == "ShS") {
 
        std::cout << "Icrease(I) or Decrease(D)? "; 
        std::cin >> IorD;
 
        while (IorD != 'i' && IorD != 'D' && IorD != 'd' && IorD != 'I') {
 
            std::cout << "Your entered data uncorrect, enter again, please: ";
            std::cin >> IorD;
        }
 
        switch (IorD) {
 
        case 'I': { ptr->ShellSortIncrease(Mass); break; }
        case 'i': { ptr->ShellSortIncrease(Mass); break; }
        case 'D': { ptr->ShellSortDecrease(Mass); break; }
        case 'd': { ptr->ShellSortDecrease(Mass); break; }
        }
    }
}
 
int main() {
 
    int num;
    char symbol;
    std::string which_sort;
 
    std::cout << "Can you write, how nums do u want?\n";
    std::cout << "Massive will has\n"; 
    std::cin >> num;
 
    double *Massive = new double[num];
    SortChoice to(num);
 
    std::cout << "What method of filling do u prefer? Hand(H) or Random(R)? ";
    std::cin >> symbol;
 
    while (symbol != 'H' && symbol != 'R' && symbol != 'r' && symbol != 'h') {
 
        std::cout << "Your entered data uncorrect, enter again, please: ";
        std::cin >> symbol;
    }
 
    std::cout << "Your massive: ";
 
    switch (symbol) {
 
    case 'H':
        for (int i = 0; i < num; i++)
            std::cin >> Massive[i];
        break;
 
    case 'h':
        for (int i = 0; i < num; i++)
            std::cin >> Massive[i];
        break;
 
    case 'R':
        srand(time(NULL));
 
        for (int i = 0; i < num; i++) {
 
            Massive[i] = rand() % num;
            std::cout << Massive[i] << " ";
        }
        break;
 
    case 'r':
        srand(time(NULL));
 
        for (int i = 0; i < num; i++) {
 
            Massive[i] = rand() % num;
            std::cout << Massive[i] << " ";
        }
        break;
    }
 
    std::cout << "\nWhat sorting method do u want to use? BubleSort(BS), ShakerSort(SS), ShellSort(ShS): ";
    std::cin >> which_sort;
 
    to.choice(which_sort, Massive);
 
    std::cout << "\nResult after sorting:\n";
 
    for (int i = 0; i < num; i++)
        std::cout << Massive[i] << " ";
 
    std::cout << std::endl;
 
    delete[] Massive;
    system("pause");
    return 0;
}
Что было исправлено:
1) Глобальная переменная(и вправду быдлокодерство);
2) Убрал using namespace std, всё же, ввести за привычку не помешают, тем более если советуют()Было бы классно, если бы ещё и объяснили почему (= );
3) Занёс все сортировки в один класс SortChoice, правда я не понял всё равно, как comparator использовать, можете привести пример, прошу.
Также есть вопрос, я когда сделал void *SortChoice::... я убрал return, и написало error C4716: 'SortChoice::choice': must return a value. Это из-за указателя?
0
143 / 92 / 34
Регистрация: 30.01.2018
Сообщений: 469
21.01.2019, 21:51 24
Цитата Сообщение от cinekst_207 Посмотреть сообщение
Это из-за указателя?
Да

void * обозначает, что будет возвращен указатель неопр. типа (int, float, MyClass etc)

А зачем в сортировках массивы возвращать, вы все равно и так их меняете по указателю
1
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
21.01.2019, 22:07  [ТС] 25
Pashka Durov, бэлин, точно, спасибо XD

Добавлено через 1 минуту
eva2326, а можете пожалуйста объяснить по поводу возвращаемого резалта в пост-версии инкремента? Как это в коде реализуется например, очень интересно
0
143 / 92 / 34
Регистрация: 30.01.2018
Сообщений: 469
21.01.2019, 22:17 26
cinekst_207, цикл с ++i отрабатывает быстрее на 300 наносекунд при 100 итерациях
1
1659 / 488 / 106
Регистрация: 17.05.2015
Сообщений: 1,497
21.01.2019, 22:31 27
Цитата Сообщение от cinekst_207 Посмотреть сообщение
Так а как рандомность чисел посекундно сделать без <ctime>? У меня же написан srand(time(0))
Эммм... ))
Не заметила)))
Значит <ctime> действительно нужен)

Цитата Сообщение от cinekst_207 Посмотреть сообщение
Вместо using namespace std постоянно писать std::? В чем, как вы говорите, "сокральный" смысл постоянно писать эту ерунду
Рассуждайте логически)
Зачем то же придумали "пространство имён".

На самом деле они нужны, что бы:
1. Избежать коллизий имён.

2. Улучшается читабельность кода.
Сразу понятно откуда взялась та, или иная функция, или класс.

Реальные проекты часто состоят из множества различных библиотек,
которые писали разные люди в разное время.

Как можно гарантировать, что не будет ошибок из-за того,
что в разных библиотеках используются одни и те же названия?

Например, вы видите код:

C++
1
2
3
...
const auto result = rand();  //<--- откуда взялся этот rand?
...
а если так?

C++
1
2
3
4
...
const auto result1 = std::rand();  
const auto result2 = tools::rand();
...
Если же вы задействуете глобальный using namespace std; где нибудь в хэдере,
и окажется, что в разных библиотеках одинаковые имена - компилятор без указания пространства имен не сможет понять, какую именно версию вы имеете ввиду.

У конструкции: using namespace std; (вместо std можно подставить другое имя)
есть реально полезное свойство:

Я приведу кусочек текста взятого по ссылке из другого источника.

Вызываем оптимальную функцию, на примере std::swap и её специализации в разных пространствах имен.

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

C++
1
2
3
4
5
6
template <class T>
void my_function(T& value1, T& value1) {
    // ...
    std::swap(value1, value2); // не оптимальное решение!
    // ...
}
Неоптимальность решения заключается в том, что пользовательские типы могут иметь свою функцию swap, которая работает намного эффективнее стандартной версии:

C++
1
2
3
4
namespace some_namespace {
    class my_vector;
    void swap(my_vector& value1, my_vector& value2);
} // some_namespace
Очень простым решением проблемы будет исправить код следующим образом:

C++
1
2
3
4
5
6
7
template <class T>
void my_function(T& value1, T& value1) {
    using std::swap;
    // ...
    swap(value1, value2);
    // ...
}
Теперь компилятор в первую очередь будет пытаться найти функцию swap из пространств имен параметров value1 и value2. Другими словами, если value1 и value2 являются экземплярами класса some_namespace::my_vector, то компилятор в первую очередь будет пытаться использовать swap из some_namespace. Если в пространствах имен параметров value1 и value2 не будет функции swap, компилятор будет использовать std::swap.

Почему происходит именно так? Потому что компилятор должен выполнить Argument Dependent Lookup (он же Koenig Lookup) прежде чем пытаться сделать вызов функции из using. Именно этим трюком пользуется boost::swap, а boost::numeric_cast использует аналогичный подход для функций floor, ceil и др.

(ц)Хабр "с++ трюки и советы из Boost на каждый день"
Добавлено через 10 минут
Цитата Сообщение от cinekst_207 Посмотреть сообщение
можете пожалуйста объяснить по поводу возвращаемого резалта в пост-версии инкремента?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
int main()
{
    int val = 1;
    
    //увеличить на 1 и вывести в консоль
    std::cout << ++val << '\n'; // вывод: 2
    
    // сначала сохранить старое значение (сделать копию), 
    // затем увеличить на 1, 
    // затем вывести в консоль старое значение
    std::cout << val++ << '\n'; // вывод: 2
    
    // на предыдущем этапе значение увеличилось на 1
    std::cout << val << '\n'; // вывод: 3
}

На самом деле для примитивных типов, таких как int разница не существенная.
Компиляторы сегодня достаточно умны, и могут оптимизировать такие случаи.

Но если в качестве счетчика используется какой то более сложный тип данных,
например итератор, то напрасное использования постфикса
может привести к напрасному ухудшению эффективности кода.
1
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
21.01.2019, 22:38  [ТС] 28
Pashka Durov, я так почитал, оказывается, я могу, грубо говоря, написать что постинкрементирую переменную, и потом старое значение сохранить и где-то использовать? Интересно, зачем это вообще нужно? Разве, если нам нужно "прошлое" значение инкриментированной переменной мы не можем просто создать новую переменную и инициализировать как n - 1?
0
143 / 92 / 34
Регистрация: 30.01.2018
Сообщений: 469
21.01.2019, 23:28 29
Цитата Сообщение от cinekst_207 Посмотреть сообщение
Интересно, зачем это вообще нужно?
Сейчас приведу не очень качественный пример, но суть, думаю, поймете
C++
1
2
3
4
5
6
while(true)
{
static int a=0;
arr[a]=a;
a++;
}
Можем сократить код:
C++
1
2
3
4
5
6
while(true)
{
static int a=0;
arr[a]=a++;
 
}
Результат не изменится, но кода меньше
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
22.01.2019, 00:12 30
Цитата Сообщение от Pashka Durov Посмотреть сообщение
Результат не изменится, но кода меньше
А теперь внимательно прочитайте эту статью и сами исправьте свою ошибку.
1
143 / 92 / 34
Регистрация: 30.01.2018
Сообщений: 469
22.01.2019, 00:19 31
valen10, мда действительно, но помогло добавление скобок:

C++
1
2
3
4
5
6
while(true)
{
static int a=0;
arr[a]=(a)++;
 
}
0
22.01.2019, 00:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.01.2019, 00:19
Помогаю со студенческими работами здесь

Моды и другие улучшения для Дальнобойщиков 2
1.Какие впечатления по игре 2.Где можно скачать НОРМАЛЬНЫЕ моды (тоесть новые машины, обновлённая...

Опции компиляторов для улучшения производительности
Провел простой тест на сравнение производительности между Си и С++. Тест заключается в поиске...

Апгрейд для улучшения баланса в комплектующих.
Всем привет от новенького! Есть у меня такой ПК, в принципе для моих потребностей и даже для игр...

Программа для улучшения производительности системы
На ХР пользовался Norton Utilities. Для 8 не могу найти NU на русском языке. Где скачать NU для 8...


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

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru