Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Hellko
6 / 6 / 1
Регистрация: 17.11.2012
Сообщений: 65
#1

Найти ошибку в перегрузке копиконструктора и операторов - C++

26.05.2013, 21:18. Просмотров 422. Ответов 11
Метки нет (Все метки)

Вот код. в QT отлично работает. а в Visual Studio выдает ошибку на строке
C++
1
(a+b).show();
помогите понять в чем проблема.

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
#include <iostream>
using namespace std;
 
struct vec {double x,y,z;};
class arr_vec {
private:
    double *x;
    double *y; //указатели на координаты
    double *z;
    int n;//количество элементов массива
public:
    arr_vec(int);//конструктор принимает количество элементов массива
    ~arr_vec();//деструктор
    void set(int,vec); //устанавливает новый вектор vec на позицию int
    vec operator[](int) const;//оператор возвращает вектор с позиции int
    friend arr_vec operator+(const arr_vec&,const arr_vec&);
    friend arr_vec operator*(const arr_vec&,double);
    friend arr_vec operator*(double,const arr_vec&);
    void show();
};
vec operator+(vec a, vec b); //оператор складывания массивов векторов
vec operator*(vec a, double b);//оператор умножения вектора на число
 
vec toVec(double x,double y, double z) {
    vec tmp;
    tmp.x=x;                       //функция создания вектора из 3-х чисел
    tmp.y=y;
    tmp.z=z;
    return tmp;
}
 
arr_vec::arr_vec(int N) { //описание конструктора
    n=N;
    x=new double[n]; //созаём массив из n элементов иксовых координат
    y=new double[n];
    z=new double[n];
    for(int i=0;i<n;i++) {x[i]=i; y[i]=i+1; z[i]=i+2;} //по умолчанию запполнение всего массива дефолтными значениями
}
 
arr_vec::~arr_vec() { //описание деструктора
    delete[]x;
    delete[]y;
    delete[]z;
}
 
void arr_vec::set(int N, vec tmp) { //функция вместо N-ого ветора вставляет этот вектор
    if(n<N) return;
    x[N]=tmp.x;
    y[N]=tmp.y;
    z[N]=tmp.z;
}
 
vec arr_vec::operator [](int N) const { //возвращает вектор с номера N
    return toVec(x[N],y[N],z[N]);
}
 
arr_vec operator+(const arr_vec& a,const arr_vec& b) { //оператор складывания массивов векторов
    arr_vec c(a.n);
    for(int i=0; i<c.n; i++)
        c.set(i,a[i]+b[i]);
    return c;
}
 
vec operator+(vec a, vec b) { //оператор складывания векторов
    return toVec(a.x+b.x,a.y+b.y,a.z+b.z);
}
 
vec operator*(vec a, double b) {//оператор умножения векторов
    return toVec(a.x*b,a.y*b,a.z*b);
}
 
arr_vec operator*(const arr_vec& a,double k) {//оператор умножения матрицы векторов на число
    arr_vec c(a.n);
    for(int i=0; i<c.n; i++) {
        c.set(i,a[i]*k);
    }
    return c;
}
 
arr_vec operator*(double k, const arr_vec& a) {//умножения числа на вектор; //константные ссылки
    return a*k;
}
 
void arr_vec::show() {
    cout<<endl<< "X: "; for(int i=0;i<n;i++) cout<<x[i]<<"  ";
    cout<<endl<< "Y: "; for(int i=0;i<n;i++) cout<<y[i]<<"  ";
    cout<<endl<< "Z: "; for(int i=0;i<n;i++) cout<<z[i]<<"  ";
    cout<<endl;
}
 
int main() {
    arr_vec a(5),b(5);
    vec a1,a2,a3,a4;
    a1=toVec(1,1,1);
    a2=toVec(2,1,0);
    a3=toVec(4,3,5);
    a4=toVec(1,-1,9);
    a.set(0,a1);
    a.set(1,a2);
    b.set(0,a3);
    b.set(1,a4);
    a.show();
    b.show();
    (a+b).show();
    a.show();
    (a*5).show();
    (5*a).show();
}
В Visual Studio работает если поменять код операторов + и * на такой:
C++
1
2
3
4
5
6
7
arr_vec operator+(const arr_vec& a,const arr_vec& b) { //оператор складывания массивов векторов
    arr_vec *c;
    c=new arr_vec(a.n);
    for(int i=0; i<c->n; i++)
        c->set(i,a[i]+b[i]);
    return *c;
}
но перестает работать если добавить копиконструктор сделанный так:
C++
1
2
3
4
5
6
7
8
arr_vec::arr_vec(const arr_vec& A) {
    n=A.n;
    for(int i=0; i<n; i++) {
        x[i]=A.x[i];
        y[i]=A.y[i];
        z[i]=A.z[i];
    }
}
Что я не так делаю?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.05.2013, 21:18     Найти ошибку в перегрузке копиконструктора и операторов
Посмотрите здесь:

О перегрузке операторов - C++
Вот у меня есть код программы : #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; class A ...

Ошибка в перегрузке операторов? - C++
не могу понять в чем ошибка class cMatrix { private: int rows; int columns; public:

Тестовые вопросы по перегрузке операторов - C++
Нужно составить 10 тестовых вопросов по Перегрузке операторов (ООП) Кто чем может пли_з помог_ите.

Ошибка при перегрузке операторов - C++
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; class fraction { public: int numerator; int denominator; fraction(); ...

Ошибки при перегрузке операторов - C++
Ну не могу,не получается самостоятельно разобрать свои ошибки(( Они по большей части повторяются. Помогите пожалуйста. ошибки...

Ошибка при перегрузке операторов. - C++
Здравствуйте! Возникла необходимость создать свой класс-обертку для работы с большими числами. Бибилиотека mpir=порт GMP. Пример рабочий:...

Ошибка при перегрузке операторов в классе - C++
Я создал класс myNVector для работы с векторами произвольного размера: в заголовочном файле: class myNVector { public: ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
26.05.2013, 21:30     Найти ошибку в перегрузке копиконструктора и операторов #2
Вместо того, чтобы хранить в контейнере arr_vec структуры vec, вы храните сами поля этой структуры.
Качество кода резко падает, поскольку классы сильно связаны.

У вас есть динамические данные в массиве, но нет ни конструктора копирования, ни оператора присваивания. Поэтому и получаете не Б-г весть что.
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
26.05.2013, 21:31     Найти ошибку в перегрузке копиконструктора и операторов #3
C++
1
2
3
4
5
6
7
8
arr_vec::arr_vec(arr_vec& A) {
    n=A.n;
    for(int i=0; i<n; i++) {
        x[i]=A.x[i];
        y[i]=A.y[i];
        z[i]=A.z[i];
    }
}
без const
Hellko
6 / 6 / 1
Регистрация: 17.11.2012
Сообщений: 65
26.05.2013, 21:51  [ТС]     Найти ошибку в перегрузке копиконструктора и операторов #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
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
#include <iostream>
using namespace std;
 
struct vec {double x,y,z;};
class arr_vec {
private:
    vec *x;
    int n;//количество элементов массива
public:
    arr_vec(int);//конструктор принимает количество элементов массива
    arr_vec(const arr_vec&);
    ~arr_vec();//деструктор
    void set(int,vec); //устанавливает новый вектор vec на позицию int
    void operator=(const arr_vec&);
    vec operator[](int) const;//оператор возвращает вектор с позиции int
    friend arr_vec operator+(const arr_vec&,const arr_vec&);
    friend arr_vec operator*(const arr_vec&,double);
    friend arr_vec operator*(double,const arr_vec&);
    void show();
};
 
vec operator+(vec a, vec b); //оператор складывания массивов векторов
vec operator*(vec a, double b);//оператор умножения вектора на число
 
arr_vec::arr_vec(const arr_vec& A) {
        n=A.n;
        x=new vec [n];
        for(int i=0; i<n; i++)
            x[i]=A.x[i];
}
 
void arr_vec::operator=(const arr_vec& A) {
        n=A.n;
        for(int i=0; i<n; i++) x=A.x;
}
 
vec toVec(double x,double y, double z) {
    vec tmp;
    tmp.x=x;                       //функция создания вектора из 3-х чисел
    tmp.y=y;
    tmp.z=z;
    return tmp;
}
 
arr_vec::arr_vec(int N) { //описание конструктора
    n=N;
    x=new vec [n];
    for(int i=0;i<n;i++) {x[i].x=i; x[i].y=i+1; x[i].z=i+2;} //по умолчанию запполнение всего массива дефолтными значениями
}
 
arr_vec::~arr_vec() { //описание деструктора
    delete[]x;
}
 
void arr_vec::set(int N, vec tmp) { //функция вместо N-ого ветора вставляет этот вектор
    if(n<N) return;
    x[N]=tmp;
}
 
vec arr_vec::operator [](int N) const { //возвращает вектор с номера N
    return x[N];
}
 
arr_vec operator+(const arr_vec& a,const arr_vec& b) { //оператор складывания массивов векторов
    arr_vec *c;
    c=new arr_vec(a.n);
    for(int i=0; i<c->n; i++)
        c->set(i,a[i]+b[i]);
    return *c;
}
 
vec operator+(vec a, vec b) { //оператор складывания векторов
    return toVec(a.x+b.x,a.y+b.y,a.z+b.z);
}
 
vec operator*(vec a, double b) {//оператор умножения векторов
    return toVec(a.x*b,a.y*b,a.z*b);
}
 
arr_vec operator*(const arr_vec& a,double k) {//оператор умножения матрицы векторов на число
    arr_vec *c;
    c=new arr_vec(a.n);
    for(int i=0; i<c->n; i++) {
        c->set(i,a[i]*k);
    }
    return *c;
}
 
arr_vec operator*(double k, const arr_vec& a) {//умножения числа на вектор; //константные ссылки
    return a*k;
}
 
void arr_vec::show() {
    cout<<endl<< "X: "; for(int i=0;i<n;i++) cout<<x[i].x<<"  ";
    cout<<endl<< "Y: "; for(int i=0;i<n;i++) cout<<x[i].y<<"  ";
    cout<<endl<< "Z: "; for(int i=0;i<n;i++) cout<<x[i].z<<"  ";
    cout<<endl;
}
 
int main() {
    arr_vec a(5),b(5);
    vec a1,a2,a3,a4;
    a1=toVec(1,1,1);
    a2=toVec(2,1,0);
    a3=toVec(4,3,5);
    a4=toVec(1,-1,9);
    a.set(0,a1);
    a.set(1,a2);
    b.set(0,a3);
    b.set(1,a4);
    a.show();
    b.show();
    (a+b).show();
    a.show();
    (a*5).show();
    (5*a).show();
}
zss
Модератор
Эксперт С++
6321 / 5905 / 1913
Регистрация: 18.12.2011
Сообщений: 15,184
Завершенные тесты: 1
26.05.2013, 21:57     Найти ошибку в перегрузке копиконструктора и операторов #5
Чтобы работало
(a+b).show();
надо, чтобы operator+ возвращал не значение, а ссылку.
vec& operator+(vec a, vec b);
Hellko
6 / 6 / 1
Регистрация: 17.11.2012
Сообщений: 65
26.05.2013, 22:00  [ТС]     Найти ошибку в перегрузке копиконструктора и операторов #6
Цитата Сообщение от zss Посмотреть сообщение
Чтобы работало
(a+b).show();
надо, чтобы operator+ возвращал не значение, а ссылку.
vec& operator+(vec a, vec b);
почему? У меня теперь заработало. (возвращаю значение)
В чем разница между возвращением ссылки и значения? Разве переменная уже не удалится которую я возвращаю, т.е. если я верну ссылку то она уже будет куском мусора?
zss
Модератор
Эксперт С++
6321 / 5905 / 1913
Регистрация: 18.12.2011
Сообщений: 15,184
Завершенные тесты: 1
26.05.2013, 22:16     Найти ошибку в перегрузке копиконструктора и операторов #7
Если пишем c=a+b;c.show();
то show() вызывается для сохраненной копии.
(a+b).show(); вызывается для чего-то временного.
Может сработать, а может и нет.
Hellko
6 / 6 / 1
Регистрация: 17.11.2012
Сообщений: 65
26.05.2013, 22:16  [ТС]     Найти ошибку в перегрузке копиконструктора и операторов #8
Слегка поправил последнюю версию ибо в спешке исправлял в прошлый раз:
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
#include <iostream>
using namespace std;
 
struct vec {double x,y,z;}; //структура векторов содержащая значения х у z
class arr_vec {
private:
    vec *x; //объявляем указатель на вектор (х - будет массивом векторов)
    int n;//количество элементов массива
public:
    arr_vec(int);//конструктор принимает количество элементов массива
    arr_vec(const arr_vec&); //копиконструктор
    ~arr_vec();//деструктор
    void set(int,vec); //устанавливает новый вектор vec на позицию int
    void operator=(const arr_vec&); //оператор присваивания
    vec operator[](int) const;//оператор возвращает вектор с позиции int
    friend arr_vec operator+(const arr_vec&,const arr_vec&);
    friend arr_vec operator*(const arr_vec&,double); //ВЕКТОР УМНОЖИТЬ НА ЧИСЛО
    friend arr_vec operator*(double,const arr_vec&);  //ЧИСЛО УМНОЖИТЬ НА ВЕКТОР
    void show();
};
 
vec operator+(vec a, vec b); //оператор складывания массивов векторов (прототип, чтоб компилятор знал что он есть)
vec operator*(vec a, double b);//оператор умножения вектора на число (аналогично)
 
arr_vec::arr_vec(const arr_vec& A) { //копиконструктор
        n=A.n;      //количество элементов теперь как в массиве А
        x=new vec [n];  //создадим массив векторов из n штук в переменной х
        for(int i=0; i<n; i++)
            x[i]=A.x[i];    //скопируем все значения из А в наш массив
}
 
void arr_vec::operator=(const arr_vec& A) {
        n=A.n;
                x=new vec[n];   //оператор присваивания аналогичен копиконструктору
        for(int i=0; i<n; i++)
                        x[i]=A.x[i];
}
 
vec toVec(double x,double y, double z) {
    vec tmp;
    tmp.x=x;                       //функция создания вектора из 3-х чисел
    tmp.y=y;
    tmp.z=z;
    return tmp;
}
 
arr_vec::arr_vec(int N) { //описание конструктора
    n=N;        //количество элементов массива теперь n=N
    x=new vec [n];  //создадим массив из n элементов
    for(int i=0;i<n;i++) {x[i].x=i; x[i].y=i+1; x[i].z=i+2;} //по умолчанию запполнение всего массива дефолтными значениями
}
 
arr_vec::~arr_vec() { //описание деструктора
    delete[]x;
}
 
void arr_vec::set(int N, vec tmp) { //функция вместо N-ого ветора вставляет этот вектор
    if(n<N) return; //если в массиве 10 элементов а мы хотим записать в 120ый элемент то ничего не делать.
    x[N]=tmp;   //иначе вектор tmp присвоить на место N-ого
}
 
vec arr_vec::operator [](int N) const { //возвращает вектор с номером N
    return x[N];
}
 
arr_vec operator+(const arr_vec& a,const arr_vec& b) { //оператор складывания массивов векторов
    arr_vec c(a.n); //создадим новый массив С с количеством элементов как в а.
    for(int i=0; i<c.n; i++)
        c.set(i,a[i]+b[i]); //присвоим всем элементам значения суммы векторов по элементно
    return c; //вернем этот массив
}
 
vec operator+(vec a, vec b) { //оператор складывания векторов
    return toVec(a.x+b.x,a.y+b.y,a.z+b.z);
}
 
vec operator*(vec a, double b) {//оператор умножения векторов
    return toVec(a.x*b,a.y*b,a.z*b);
}
 
arr_vec operator*(const arr_vec& a,double k) {//оператор умножения массива векторов на число
    arr_vec c(a.n);
    for(int i=0; i<c.n; i++) {
        c.set(i,a[i]*k); //аналогично оператор +
    }
    return c;
}
 
arr_vec operator*(double k, const arr_vec& a) {//умножения числа на вектор
    return a*k; //используем уже существующую функцию для выполнения того же самого что и выше. только поменяв местами.
}
 
void arr_vec::show() {
    cout<<endl<< "X: "; for(int i=0;i<n;i++) cout<<x[i].x<<"  ";
    cout<<endl<< "Y: "; for(int i=0;i<n;i++) cout<<x[i].y<<"  ";
    cout<<endl<< "Z: "; for(int i=0;i<n;i++) cout<<x[i].z<<"  ";
    cout<<endl;
}
 
int main() {
    arr_vec a(5),b(5); //создадим 2 массива из 5 элементов
    vec a1,a2,a3,a4; //создадим 4 пустых вектора
    a1=toVec(1,1,1);    //вектор а1 будет (1,1,1) итд
    a2=toVec(2,1,0);
    a3=toVec(4,3,5);
    a4=toVec(1,-1,9);
    a.set(0,a1); //на 0 место в массиве "а" запишем вектор а1. итд.
    a.set(1,a2);
    b.set(0,a3);
    b.set(1,a4);
    a.show(); //вывести на экран а, и б, их сумму, и опять а, и а*5, и 5*а.
    b.show();
    (a+b).show();
    a.show();
    (a*5).show();
    (5*a).show();
}
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
26.05.2013, 22:18     Найти ошибку в перегрузке копиконструктора и операторов #9
Цитата Сообщение от zss Посмотреть сообщение
Чтобы работало
(a+b).show();
надо, чтобы operator+ возвращал не значение, а ссылку.
vec& operator+(vec a, vec b);
не должен он возвращать ссылку, и для объекта это будет работать
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
26.05.2013, 22:28     Найти ошибку в перегрузке копиконструктора и операторов #10
Цитата Сообщение от zss Посмотреть сообщение
Чтобы работало
(a+b).show();
надо, чтобы operator+ возвращал не значение, а ссылку.
vec& operator+(vec a, vec b);
Неправда. Временное значение так же будет работать. Да и откуда ссылку взять для возвращения, если в функции создается новый объект!? )

Добавлено через 1 минуту
Цитата Сообщение от Hellko Посмотреть сообщение
vec operator[](int) const;//оператор возвращает вектор с позиции int
А вот тут пригодилась бы сигнатура
C++
1
const vec &operator[](int) const
и дополнительно неконстантный вариант для модификации значения
C++
1
vec &operator[](int)
Hellko
6 / 6 / 1
Регистрация: 17.11.2012
Сообщений: 65
26.05.2013, 23:18  [ТС]     Найти ошибку в перегрузке копиконструктора и операторов #11
Спасибо lemegeton.
У меня еще вопрос. Я не перегружал оператор присваивания для структуры vec. Это нормально? Как его перегрузить для структур vec и вообще надо ли?
Использую тут:
C++
1
2
3
4
void arr_vec::set(int N, vec tmp) {
    if(n<N) return;
    x[N]=tmp;   
}
И еще. Копи конструктор и оператор присваивания они идентичны внутри. Всегда ли так? Можно ли использовать один из них для выполнения другого? Чтобы не писать один и тот же код дважды.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.05.2013, 07:51     Найти ошибку в перегрузке копиконструктора и операторов
Еще ссылки по теме:

При перегрузке операторов не записывает значение - C++
Собственно вот мой код: class.h class Otrezku { public: Otrezku(); Otrezku(float , float , float , float ); ...

Ошибка в перегрузке операторов для класса - итератора - C++
Добрый вечер. Есть заготовка программы для работы с матрицей, построенной из узлов с четырьмя связями (вверх, вниз, влево, вправо)....

Можно ли при перегрузке операторов задавать дополнительные параметры? - C++
Здравствуйте. Мне в функции перегрузки оператора нужно передать дополнительный параметр, можно ли это сделать? void operator...

Сколько используется параметров при перегрузке унарных операторов как френд-функций? - C++
Вопрос следующий интересует: При перегрузке унарных операторов как френд-функций сколько используется параметров? Также при перегрузке...

Не могу найти ошибку (перегрузка операторов) - C++
Чето после НГ туплю(( Изучаю перегрузку операторов и не могу найти ошибку в простенькой программе( Помогите пожалуйста. ...


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

Или воспользуйтесь поиском по форуму:
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
27.05.2013, 07:51     Найти ошибку в перегрузке копиконструктора и операторов #12
Цитата Сообщение от Hellko Посмотреть сообщение
Копи конструктор и оператор присваивания они идентичны внутри.
Они не идентичны, но похожи. В операторе присваивания нет списков ининицализации и уже существуют данные, т.е. придется освобождать возможно выделенную память. Кроме того, в операторе присваивания нужно проверить, не совпадает ли объект с присваиваемым.

Поскольку эти операции действительно похожи, хорошо бы выделить саму процедуру копирования в отдельный метод. Что-то вроде:
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
 public:
  arr_vec &copyFrom(const arr_vec &other)  {
    // проверка, что объекты разные
    if (this != &other) {
      // тут надо написать свой код. :) 
      // освобождение выделенной памяти,
      /*
       *delete [] x;
       */
      ...
      // копирование данных из переданного объекта
      /*
       *n = other.n;
       *x = new double[n];
       *for (int i = 0; i != n; ++i) {
       *  x[i] = other.x[i];
       *}
       */
      ...
    }
    return *this;
  }
  // конструктор копирования.
  // динамической переменной присваивается значение 0
  // такое значение можно безопасно удалять delete'ом.
  arr_vec(const arr_vec &other) : x(0) {
    copyFrom(other);
  }
  // оператор присваивания
  // нет списка инициализации, метод однозначно
  // должен освобождать память, выделенную под x
  arr_vec &operator=(const arr_vec &other) {
    return copyFrom(other);
  }
Yandex
Объявления
27.05.2013, 07:51     Найти ошибку в перегрузке копиконструктора и операторов
Ответ Создать тему
Опции темы

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