Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/9: Рейтинг темы: голосов - 9, средняя оценка - 5.00
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1

Где почитать про перегрузку поразрядных логических операций (|, &, ^)

27.10.2014, 15:44. Показов 2030. Ответов 32
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Подскажите пособие, где как можно подробно описывается перегрузка поразрядных логических операций (|, &, ^).
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.10.2014, 15:44
Ответы с готовыми решениями:

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

Рассчитать значение функции с использованием оператора if / else и логических операций && и || (При необходимости)
Помогите, - пожалуйста написать программу, которая рассчитывает значение функции с использованием оператора if / else и логических...

Програма которая рассчитывает значение функции с использованием оператора if/else и логических операций && и ||
Написать программу на языке С #, которая рассчитывает значение функции с использованием оператора if/else и логических операций &&...

32
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
27.10.2014, 16:46
А что, есть какие-то отличия от перегрузки арифметических?
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
27.10.2014, 16:47  [ТС]
я только начал изучать эту тему, поэтому не знаю)
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.10.2014, 17:43
Nickolay0512, перегрузка операторов подразумевает его реализацию для пользовательского типа. И совершенно не важно какой оператор перегружается, если перегрузка вообще для него допустима.
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
27.10.2014, 17:45  [ТС]
Tulosba, Вот я пишу класс Vector, в котором могут быть значения или 0 или 1.
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
#include <iostream>
#include <cstring>
using namespace std;
class Vector
{
private:
    size_t size_;
    char data[100];
public:
    Vector();
    Vector(const int, const size_t);
    Vector(char*);
    size_t GetSize();
    void SetSize(size_t);
    const char operator[](size_t i) const
    {
        return data[i];
    }
    friend ostream& operator << (ostream &stream, Vector &obj)//перегрузка <<
    {
        for (size_t i = 0; i < obj.size_; i++)
            stream << obj.data[i] << " ";
        stream << endl;
        return stream;
    }
    friend istream& operator >> (istream &stream, Vector &obj)//перегрузка >>
    {
        for (size_t i = 0; i < obj.size_; i++)
            stream >> obj.data[i];
        return stream;
    }
};
Vector::Vector()//конструктор 
{
    size_ = 10;//по умолчанию вектор будет состоять из 10 элементов
    for (size_t i = 0; i < size_; i++)//заполняем вектор нулями
    {
        data[i] = 0;
    }
}
Vector::Vector(const int value, const size_t size)//конструктор
{
    size_ = size;
    for (int i = 0; i < size; i++)
    {
        data[i] = (char)value;//приводим тип int к типу char
    }
}
Vector::Vector(char* value)//конструктор
{
    size_ = strlen(value);//количество элементов в векторе = количеству символов в строке
    for (int i = 0; i < size_; i++)
    {
        data[i] = value[i];//приводим тип int к типу char
    }
}
void Vector::SetSize(size_t size)//сеттер
{
    size_ = size;
}
size_t Vector::GetSize()
{
    return size_;
}
Можете показать перегрузку одного из побитовых операций для двух векторов?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.10.2014, 17:59
Для одинаковых размеров например так:
C++
1
2
3
4
5
6
7
8
9
10
11
Vector operator|(const Vector& lhs, const Vector& rhs)
{
    Vector result(lhs.size_);
 
    for( size_t i=0; i<lhs.size_; ++i )
    {
        result.data[i] = lhs.data[i] | rhs.data[i];
    }
 
    return result;
}
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
27.10.2014, 18:02  [ТС]
Tulosba, Спасибо. А вот еще вопрос. Если я в майне пишу заполнение вектора
C++
1
2
3
4
5
for(int i = 0; i < N; i++)
    {
        cout << "Введите А" << i << endl;
        cin >> a[i];
    }
вылетает ошибка отсутствует оператор ">>", соответствующий этим операндам типы операндов: std::istream >> char. Видимо это потому, что в перегрузке [] возвращается char. Но когда я пишу
C++
1
2
3
4
for (int i = 0; i < a.GetSize(); i++)
            {
                cout << a[i] << " ";
            }
проблем нет. Как мне быть с вводом вектора?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
27.10.2014, 18:06
Остальная часть где? Как вектор объявлен?
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
27.10.2014, 18:08  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
        int N;
    cout << "Введите кол-во элементов вектора: ";
    cin >> N;
    Vector a;
    cout << "Заполните вектор" << endl;
    for(int i = 0; i < N; i++)
    {
        cout << "Введите А" << i << endl;
        cin >> a[i];
    }
        for (int i = 0; i < a.GetSize(); i++)
            {
                cout << a[i] << " ";
            }
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.10.2014, 18:10
Цитата Сообщение от Nickolay0512 Посмотреть сообщение
вылетает ошибка отсутствует оператор ">>", соответствующий этим операндам типы операндов: std::istream >> char.
Должно работать.
http://ideone.com/0yG4i6
В твоем случае дело в const.
Помимо:
C++
1
2
3
4
const char operator[](size_t i) const
{
   return data[i];
}
Нужна ещё не константная версия:
C++
1
2
3
4
char& operator[](size_t i)
{
   return data[i];
}
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
28.10.2014, 11:24  [ТС]
Разобрался. Оказывается надо было в перегрузке [] возвращать по ссылке

Добавлено через 16 часов 47 минут
Tulosba, Вроде разобрался. Теперь нужно написать такой же класс, только выделять память динамически. Я написал вот так:
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
328
329
330
331
332
333
334
335
336
337
#include <iostream>
#include <cstring>
using namespace std;
class Vector
{
private:
    size_t size_;
    char *data;
public:
    Vector();
    Vector(const int, const size_t);
    Vector(const char*);
    Vector(const Vector &);//конструктор копии
    ~Vector();//деструктор
    size_t GetSize();
    void SetSize(size_t);
    void One();
    char& operator[](size_t i)
    {
        return data[i];
    }
 
    friend ostream& operator << (ostream &stream, Vector &obj)//перегрузка <<
    {
        for (size_t i = 0; i < obj.size_; i++)
            stream << obj.data[i] << " ";
        stream << endl;
        return stream;
    }
 
    friend istream& operator >> (istream &stream, Vector &obj)//перегрузка >>
    {
        for (size_t i = 0; i < obj.size_; i++)
            stream >> obj.data[i];
        return stream;
    }
    void Dopolnim(int size)//функция дополняет вектор нулями слева
    {
        size_t i;
        Vector tmp;//создаем временный вектор
        for (i = 0; i < size - size_; i++)
        {
            tmp.data[i] = data[i];//сохраним элементы меньшего вектора
            data[i] = '0';//заполняем начало вектора нулями
        }
        for (i = size - size_; i < size; i++)
            data[i] = tmp.data[i - (size - size_)];//заполняем оставшиеся элементы вектора 
        size_ = i;                            //его же элементами, которые были в начале 
        //до его расширения нулями слева
    }
    friend Vector& operator|(Vector& lhs, Vector& rhs)
    {
 
        int size1 = lhs.size_;//размеры массивов
        int size2 = rhs.size_;
 
        Vector result;
        if (size1 < size2)
        {
            lhs.Dopolnim(size2);
            result.size_ = size2;
        }
        else if (size2 < size1)
        {
            rhs.Dopolnim(size1);
            result.size_ = size1;
        }
        else result.size_ = size2;
        for (size_t i = 0; i<lhs.size_; ++i)
        {
            result.data[i] = lhs.data[i] | rhs.data[i];
        }
 
        return result;
    }
 
    friend Vector operator&(Vector& lhs, Vector& rhs)
    {
 
        int size1 = lhs.size_;//размеры массивов
        int size2 = rhs.size_;
 
        Vector result;
        if (size1 < size2)
        {
            lhs.Dopolnim(size2);
            result.size_ = size2;
        }
        else if (size2 < size1)
        {
            rhs.Dopolnim(size1);
            result.size_ = size1;
        }
        for (size_t i = 0; i<lhs.size_; ++i)
        {
            result.data[i] = lhs.data[i] & rhs.data[i];//считаем результирующий вектор
        }
        return result;
    }
 
    friend Vector operator~(Vector& lhs)
    {
 
        int size1 = lhs.size_;//размеры массивов
 
        Vector result;
        result.size_ = lhs.size_;
        for (size_t i = 0; i<lhs.size_; ++i)
        {
            //считаем результирующий вектор
            if (lhs.data[i] == '1') result.data[i] = '0';
            else result.data[i] = '1';
        }
        return result;
    }
 
    friend Vector operator^(Vector& lhs, Vector& rhs)
    {
 
 
        int size1 = lhs.size_;//размеры массивов
        int size2 = rhs.size_;
 
        Vector result;
        if (size1 < size2)
        {
            lhs.Dopolnim(size2);
            result.size_ = size2;
        }
        else if (size2 < size1)
        {
            rhs.Dopolnim(size1);
            result.size_ = size1;
        }
        for (size_t i = 0; i<lhs.size_; ++i)
            result.data[i] = lhs.data[i] ^ rhs.data[i];
        return result;
    }
 
};
Vector::Vector()//конструктор 
{
    data = new char[10];
    size_ = 10;//по умолчанию вектор будет состоять из 10 элементов
    for (size_t i = 0; i < size_; i++)//заполняем вектор нулями
    {
        data[i] = '0';
    }
}
 
Vector::Vector(const Vector &arrayToCopy) // конструктор копии
    :size_(arrayToCopy.size_)              // инициализатор размера массива
{
    data = new char[size_]; // выделить место в памяти для массива
 
    for (size_t i = 0; i < size_; i++)
        data[i] = arrayToCopy.data[i]; // заполняем массив значениями массива arrayToCopy
}
 
Vector::Vector(const int value, const size_t size)//конструктор
{
    data = new char[size];
    size_ = size;
    for (size_t i = 0; i < size; i++)
        data[i] = (char)value;//приводим тип int к типу char
}
Vector::Vector(const char* value)//конструктор
{
    size_ = strlen(value);//количество элементов в векторе = количеству символов в строке
    data = new char[size_];
    for (size_t i = 0; i < size_; i++)
        data[i] = value[i];//приводим тип int к типу char
}
 
Vector::~Vector() // десструктор 
{
    delete[] data; // освободить память, удалив массив
}
 
void Vector::SetSize(size_t size)//сеттер
{
    delete[] data;
    data = new char[size];
    size_ = size;
}
size_t Vector::GetSize()
{
    return size_;
}
 
void Vector::One()
{
    size_t i, k, j;
    for (i = 0; i<size_; i++)
    {
        if (data[i] == '0')
            continue;
        else
            break;
    }
    for (j = size_ - 1; j > i - 1; j--)
    {
        if (data[j] == '0')
            continue;
        else break;
    }
    for (k = i; k <= j; k++)
        cout << data[k] << " ";
    cout << endl;
}
int main()
{
    int n = 100;
    Vector a, b, c, d, e;
    while (n != 0)
    {
        cout << "----------MainMenu-----------" << endl;
        cout << "1. Ввести вектора. " << endl;
        cout << "2. Вывести вектора." << endl;
        cout << "3. Операция включающее ИЛИ." << endl;
        cout << "4. Операция исключающее ИЛИ." << endl;
        cout << "5. Операция И." << endl;
        cout << "6. Операция ~" << endl;
        cout << "7. Получить вектор, ограниченный слева и справа еденицами." << endl;
        cout << "0. Выход." << endl;
        cin >> n;
        system("cls");
        switch (n)
        {
        case 1:
        {
            int N;
            cout << "Введите размер вектора A: ";
            cin >> N;
            a.SetSize(N);
            cout << "Заполните вектор A" << endl;
            for (size_t i = 0; i < N; i++)
            {
                cout << "Введите А" << i << endl;
                cin >> a[i];
            }
            cout << "Введите размер вектора B: ";
            cin >> N;
            b.SetSize(N);
            cout << "Заполните вектор B" << endl;
            for (size_t i = 0; i < N; i++)
            {
                cout << "Введите B" << i << endl;
                cin >> b[i];
            }
            system("pause");
            break;
        }
        case 2:
        {
            cout << "Вектор А: " << endl;
            for (size_t i = 0; i < a.GetSize(); i++)
            {
                cout << a[i] << " ";
            }
            cout << endl;
            cout << "Вектор B: " << endl;
            for (size_t i = 0; i < b.GetSize(); i++)
            {
                cout << b[i] << " ";
            }
            cout << endl;
            system("pause");
            break;
        }
        case 3:
        {
            c = a | b;
            cout << "Вектор A|B: " << endl;
            for (size_t i = 0; i <c.GetSize(); i++)
            {
                cout << c[i] << " ";
            }
            cout << endl;
            system("pause");
            break;
        }
        case 4:
        {
            c = a ^ b;
            cout << "Вектор A^B: " << endl;
            for (size_t i = 0; i <c.GetSize(); i++)
            {
                cout << (int)c[i] << " ";
            }
            cout << endl;
            system("pause");
            break;
        }
        case 5:
        {
            c = a & b;
            cout << "Вектор A&B: " << endl;
            for (size_t i = 0; i <c.GetSize(); i++)
            {
                cout << c[i] << " ";
            }
            cout << endl;
            system("pause");
            break;
        }
        case 6:
        {
            c = ~a;
            d = ~b;
            cout << "Вектор ~A: " << endl;
            for (size_t i = 0; i <c.GetSize(); i++)
            {
                cout << c[i] << " ";
            }
            cout << endl;
            cout << "Вектор ~B: " << endl;
            for (size_t i = 0; i <d.GetSize(); i++)
            {
                cout << d[i] << " ";
            }
            cout << endl;
            system("pause");
            break;
        }
        case 7:
        {
            a.One();
            cout << endl;
            system("pause");
            break;
        }
        case 0: break;
        default:{cout << "Неверный пункт меню!" << endl; break; }
        }
    }
}
Ввод и вывод работает. При перегрузке ^,|,& возвращается какая-то ерунда. Посмотрел в отладчике и выяснил, что ерунда в result появляется после строки return result; Что я делаю не так?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
28.10.2014, 11:30
Цитата Сообщение от Nickolay0512 Посмотреть сообщение
При перегрузке ^,|,& возвращается какая-то ерунда.
В operator| понятно, потому что возвращать надо объект, а не ссылку. В ^,& вроде правильно возвращается.
Общее замечание, что аргументы не должны меняться, т.е. принимать их следует по ссылке на константу:
C++
1
const Vector&
Если для упрощения алгоритма по-прежнему хочется делать дополнение нулями, можно и вовсе передавать по значению, но уж точно не по обычной ссылке. Т.к. аргумент не должен меняться. Пользователь этого не ожидает.
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
28.10.2014, 12:25  [ТС]
Tulosba, Возвращаю по значению, все равно не получается. Заметил в отладчике, что поле ввода векторах какая-то ерунда (вектор как будто состоит а из одной единицы). В чем проблема?
Миниатюры
Где почитать про перегрузку поразрядных логических операций (|, &, ^)  
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
28.10.2014, 12:36
А зачем ты их как friend объявил? Так только с >> и << обычно делают.
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
28.10.2014, 12:38  [ТС]
nmcf, Если без friend говорит: "слишком много параметров для этой функции оператора"
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
28.10.2014, 12:45
Цитата Сообщение от Nickolay0512 Посмотреть сообщение
Заметил в отладчике, что поле ввода векторах какая-то ерунда (вектор как будто состоит а из одной единицы).
Отладчик пытается выводить символьный массив как си-строку. В твоем случае это не строка. Поэтому и смотреть надо каждый элемент отдельно.
Цитата Сообщение от Nickolay0512 Посмотреть сообщение
возвращается какая-то ерунда.
Напиши тестовый пример. Чтобы было видно, что на входе, что на выходе. Тогда можно будет говорить более предметно.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
28.10.2014, 12:47
Ну всё верно, без friend параметр только 1 - тот, что справа в выражении, а левый - сам объект.
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
28.10.2014, 12:49  [ТС]
Ввожу: Вектор А: 1 0 1 0 1 0 1 0.
Вектор B: 1 0 0 1(размеры соответственно 8 и 4)
После вызова пункта меню с операцией | получаю то что на картинке
Миниатюры
Где почитать про перегрузку поразрядных логических операций (|, &, ^)  
0
58 / 40 / 41
Регистрация: 26.09.2013
Сообщений: 347
Записей в блоге: 1
28.10.2014, 12:50  [ТС]
nmcf, Мне не нужно менять сам объект. Нужно просто вывести результат операции. Поэтому результат приходится загонять в вектор С
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
28.10.2014, 12:53
Его и не надо менять. Я тебе просто говорю, что у friend-функции, скажем, для | будет два параметра - левый и правый относительно "|" в выражении, а у обычной функции только правый, а левый сам объект. Возвращаешь же в любом случае новый.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.10.2014, 12:53
Помогаю со студенческими работами здесь

Програма которая рассчитывает значение функции с использованием оператора if/else и логических операций && и ||
Програма которая рассчитывает значениеНаписать программу на языке С #, которая рассчитывает значение функции с использованием оператора...

Версии Делфи 10 и 7. Можно где-то почитать про их особенности, про совместимость?
Переносили вы проекты из делфи 7 на делфи 10. Может знаете в чем особенности, где можно побольше информации почитать, что может не...

Что почитать про Drag&Drop?
Нужно в аплете создать пробирку, которую можна 'таскать' по аплету и в зависимости от того, где бросишь выполняются определенные действия....

Где почитать про @ ?
Знающие, подскажите ссылками на код. Как именно работает Verbatim String Literal?

Java & TomCat - где бы скачать и почитать
Посоветуйте плз где можно скачать TomCat и где бы по нему почитать что-то полезное, нужное, необходимое ?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru