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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
UrbanLynx
1 / 1 / 0
Регистрация: 13.02.2013
Сообщений: 29
#1

Функция уже определена в другом файле - C++

25.04.2013, 09:39. Просмотров 1415. Ответов 21
Метки нет (Все метки)

Который день бьюсь и не могу найти ответа, подскажите, если знаете.
Есть sparseMatrix.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
#pragma once
 
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
 
using namespace std;
 
class RowFormatMatrix
{
public:
    RowFormatMatrix(int c=0, int r=0):col(c),row(r),ia(0),ja(0),an(0){};
    RowFormatMatrix(const vector<int>& i, const vector<int>& j, const vector<double>& n, int c, int r):ia(i),ja(j),an(n),col(c),row(r){};
    RowFormatMatrix(ostream& ins);
    ~RowFormatMatrix(){};
 
    friend RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b);
    friend void printUsualMatrix(const RowFormatMatrix& matrix);
    friend void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
    friend void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
private:
    vector<int> ia; // номер компонента в ja и an, с которого начинается текущая строка
    vector<int> ja; // номера столбцов
    vector<double> an;
    int col, row;
};
 
void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c){...}
 
void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c){...}
 
RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b){...}
 
void enterUsualMatrix(RowFormatMatrix& matrix){...}
 
void enterRowFormatMatrix(RowFormatMatrix& matrix){...}
 
void printUsualMatrix(const RowFormatMatrix& matrix){...}
Его я включаю в другие файлы, скажем main.cpp, support.h и support.cpp.
Но линковщик выдает ошибки:
Код
1>support.obj : error LNK2005: "void __cdecl symbolicPart(class RowFormatMatrix const &,class RowFormatMatrix const &,class RowFormatMatrix &)" (?symbolicPart@@YAXABVRowFormatMatrix@@0AAV1@@Z) уже определен в main.obj
1>support.obj : error LNK2005: "void __cdecl numericalPart(class RowFormatMatrix const &,class RowFormatMatrix const &,class RowFormatMatrix &)" (?numericalPart@@YAXABVRowFormatMatrix@@0AAV1@@Z) уже определен в main.obj
1>support.obj : error LNK2005: "class RowFormatMatrix __cdecl operator+(class RowFormatMatrix const &,class RowFormatMatrix const &)" (??H@YA?AVRowFormatMatrix@@ABV0@0@Z) уже определен в main.obj
1>support.obj : error LNK2005: "void __cdecl enterUsualMatrix(class RowFormatMatrix &)" (?enterUsualMatrix@@YAXAAVRowFormatMatrix@@@Z) уже определен в main.obj
1>support.obj : error LNK2005: "void __cdecl enterRowFormatMatrix(class RowFormatMatrix &)" (?enterRowFormatMatrix@@YAXAAVRowFormatMatrix@@@Z) уже определен в main.obj
1>support.obj : error LNK2005: "void __cdecl printUsualMatrix(class RowFormatMatrix const &)" (?printUsualMatrix@@YAXABVRowFormatMatrix@@@Z) уже определен в main.obj
Как такое может быть? Ведь есть защита, пробовал и ifndef'ы тоже.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.04.2013, 09:39
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Функция уже определена в другом файле (C++):

Сообщение об ошибке "функция-член уже определена" - C++
Вот код #include &lt;iostream&gt; using namespace std; class Matrix { private: int **Array; int nstr, nstl; public:

Ошибка - "Функция _main уже определена" - C++
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; void check_weekday(string day) { if (day == &quot;Понедельник&quot; || day ==...

Переменная уже определена в Form_5.obj - C++
Здравствуйте, я наткнулся на следующую проблему и не могу решить. Вот имеется код файла Form_5.h: #ifndef _FORM5_H #define _FORM5_H ...

нужно чтобы функция располагалась до ее вызова, после ее вызова и в другом файле. Как это сделать? - C++
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int n, *c; void fun(int a, int b) { for (int i = 0; i &lt;...

Как одному классу узнать о другом в другом файле, если они не имеют общего наследования - C++
Есть два класса в разных файлах, первому классу нужно знать о втором и использовать указатели типа второго у себя внутри, второму нужно...

Функция setw не определена? - C++
#include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace std; int main() { cout &lt;&lt;setw(5)&lt;&lt;&quot;!!!Hello World!!!&quot; &lt;&lt; endl; // prints...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
vxg
Модератор
3155 / 1957 / 218
Регистрация: 13.01.2012
Сообщений: 7,486
25.04.2013, 10:20 #2
Цитата Сообщение от UrbanLynx Посмотреть сообщение
Ведь есть защита, пробовал и ifndef'ы тоже
и где же она? у вас ее нет. тела функций определены в заголовке. заголовок не защищен от повторного включения. где тела компонентных функций класса вообще не ясно.
UrbanLynx
1 / 1 / 0
Регистрация: 13.02.2013
Сообщений: 29
25.04.2013, 16:21  [ТС] #3
Почему жу? на 1ой строчке #pragma once

Цитата Сообщение от vxg Посмотреть сообщение
где тела компонентных функций класса вообще не ясно.
Там только конструкторы, которые инициализируют.
vxg
Модератор
3155 / 1957 / 218
Регистрация: 13.01.2012
Сообщений: 7,486
25.04.2013, 16:58 #4
Цитата Сообщение от UrbanLynx Посмотреть сообщение
#pragma once
как правило защиту от повторного включения h-файлов делают следующим образом
C++
1
2
3
4
#ifndef module_name_h
#define module_name_h
//содержимое
#endif
Цитата Сообщение от UrbanLynx Посмотреть сообщение
Там только конструкторы, которые инициализируют
а этот почему сиротой остался
C++
1
RowFormatMatrix(ostream& ins);
кстати, в остальных конструкторах ; после } не нужна

Добавлено через 1 минуту
+помещать конструкцию
C++
1
using namespace std;
в заголовок я бы не стал. хотя смотря какие цели вы преследуете. если вы ненавидите префикс std, то можно
UrbanLynx
1 / 1 / 0
Регистрация: 13.02.2013
Сообщений: 29
25.04.2013, 17:13  [ТС] #5
Цитата Сообщение от vxg Посмотреть сообщение
как правило защиту от повторного включения h-файлов делают следующим образом
Visual Studio поддерживает и #pragma once. В других прогах в аналогичной ситуации нескольких включений все прекрасно работает с #pragma once. В любом случае, как я уже написал, использование ифндефов тоже не помогает.

Цитата Сообщение от vxg Посмотреть сообщение
а этот почему сиротой остался
Скорее всего забыл объявление удалить. В любом случае это никак не влияет

Цитата Сообщение от vxg Посмотреть сообщение
если вы ненавидите префикс std, то можно
Да, именно)
vxg
Модератор
3155 / 1957 / 218
Регистрация: 13.01.2012
Сообщений: 7,486
25.04.2013, 17:17 #6
Цитата Сообщение от UrbanLynx Посмотреть сообщение
все прекрасно работает
как видим не прекрасно. кроме того ваш h-файл проклянут пользователи других систем
Цитата Сообщение от UrbanLynx Посмотреть сообщение
тоже не помогает
не верю
попробуйте сделать пустой cpp-файл соответствующий вашему h-файлу и включить его в проект
Байт
Эксперт C
15979 / 10247 / 1536
Регистрация: 24.12.2010
Сообщений: 19,327
25.04.2013, 17:24 #7
Ругается-то Линковщик...
В support.obj и main.obj одни и те же функции определены.

Добавлено через 3 минуты
Ну да! Они же у вас в хедере реализованы! Т.е. реализация попадает в оба obj-файла.
Поставь перед реализациями online

Добавлено через 1 минуту
А еще лучше - вытащи их в отдельный cpp
UrbanLynx
1 / 1 / 0
Регистрация: 13.02.2013
Сообщений: 29
25.04.2013, 17:39  [ТС] #8
Цитата Сообщение от Байт Посмотреть сообщение
Т.е. реализация попадает в оба obj-файла.
Так вот как она попадает во второй файл? Там же защита стоит, он смотрит что этот хедер уже включен и не трогает его больше. Нет?

Даже растаскивание на файлы не помогает - уже пробывал вот так:
sparseMatrix.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
#pragma once
 
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
 
using namespace std;
 
class RowFormatMatrix
{
public:
    RowFormatMatrix(int c=0, int r=0):col(c),row(r),ia(0),ja(0),an(0){};
    RowFormatMatrix(const vector<int>& i, const vector<int>& j, const vector<double>& n, int c, int r):ia(i),ja(j),an(n),col(c),row(r){};
    ~RowFormatMatrix(){}
 
    friend RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b);
    friend void printUsualMatrix(const RowFormatMatrix& matrix);
    friend void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
    friend void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
protected:
    vector<int> ia; // номер компонента в ja и an, с которого начинается текущая строка
    vector<int> ja; // номера столбцов
    vector<double> an;
    int col, row;
};
sparseMatrixRealisation.h
C++
1
2
3
4
5
6
7
8
9
10
#pragma once
 
#include "sparseMatrix.h"
 
void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b);
void enterUsualMatrix(RowFormatMatrix& matrix);
void enterRowFormatMatrix(RowFormatMatrix& matrix);
void printUsualMatrix(const RowFormatMatrix& matrix);
sparseMatrixRealisation.cpp
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
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
 
#include "sparseMatrix.h"
#include "sparseMatrixRealisation.h"
 
using namespace std;
 
// символическая часть
void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c)
{
    int firstA, lastA, firstB, lastB;
    int num;
    vector<int> ix(a.col,-1);
 
    for (int i=0; i<c.row; i++) // i - номер строки
    {
        firstA = a.ia[i];
        lastA = a.ia[i+1];
        firstB = b.ia[i];
        lastB = b.ia[i+1];
 
        c.ia.push_back(c.ja.size());
        for (int j=firstA; j<lastA; j++)
        {
            num = a.ja[j];
            c.ja.push_back(num);
            ix[num] = i;
        }
        for (int j=firstB; j<lastB; j++)
        {
            num = b.ja[j];
            if (ix[num] != i)
            {
                c.ja.push_back(num);
            }
        }
    }
    c.ia.push_back(c.ja.size());
}
 
// численная часть
void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c)
{
    int firstA, lastA, firstB, lastB, firstС, lastС;
    int num;
    vector<double> ix(a.col);
 
    for (int i=0; i<c.row; i++) // i - номер строки
    {
        firstA = a.ia[i];
        lastA = a.ia[i+1];
        firstB = b.ia[i];
        lastB = b.ia[i+1];
        firstС = c.ia[i];
        lastС = c.ia[i+1];
 
        for (int j=firstС; j<lastС; j++)
        {
            num = c.ja[j];
            ix[num] = 0;
        }
        for (int j=firstA; j<lastA; j++)
        {
            num = a.ja[j];
            ix[num] += a.an[j];
        }
        for (int j=firstB; j<lastB; j++)
        {
            num = b.ja[j];
            ix[num] += b.an[j];
        }
        for (int j=firstС; j<lastС; j++)
        {
            num = c.ja[j];
            c.an.push_back(ix[num]);
        }
    }
}
 
RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b)
{
    if (a.col != b.col || a.row != b.row) // проверка на соответствие
    {
        return RowFormatMatrix(0,0);
    }
 
    RowFormatMatrix c(a.col,a.row);
    symbolicPart(a,b,c);
    numericalPart(a,b,c);
    return c;
}
 
void enterUsualMatrix(RowFormatMatrix& matrix)
{
    vector<int> ia; 
    vector<int> ja; 
    vector<double> an;
    int col, row;
    double element;
 
    cout<<"Введите количество строк и столбцов матрицы\n";
    cin>>col>>row;
    cout<<"Введите матрицу "<<col<<"x"<<row<<":\n";
    for (int i=0; i<row; i++)
    {
        cout<<i<<"я строка ";
        ia.push_back(i);
        for (int j=0; j<col; j++)
        {
            cin>>element; 
            if (element!=0) // возможно нужно заменить на element-eps<0
            {
                ja.push_back(j);
                an.push_back(element);
            }
        }
    }
 
    RowFormatMatrix tempMatrix(ia,ja,an,col,row);
    matrix = tempMatrix;
    cout<<"Матрица задана\n";
}
 
void enterRowFormatMatrix(RowFormatMatrix& matrix)
{
    vector<int> ia; 
    vector<int> ja; 
    vector<double> an;
    int col, row;
    double element;
    int num;
 
    string line;
    istringstream stream;
 
    cout<<"Введите количество строк и столбцов матрицы: ";
    cin>>row>>col;
    cout<<"Введите матрицу в разрежено строчном формате:\n";
 
    cout<<"Введите массив ia: ";
    getline(cin,line);
    getline(cin,line);
    stream.str(line);
    while (stream >> num)
    {
        ia.push_back(num);
    }
 
    cout<<"Введите массив ja: ";
    getline(cin,line);
    stream.str(line);
    while (stream >> num)
    {
        ja.push_back(num);
    }
 
    cout<<"Введите массив an: ";
    getline(cin,line);
    stream.str(line);
    while (stream >> element)
    {
        an.push_back(element);
    }
 
    RowFormatMatrix tempMatrix(ia,ja,an,col,row);
    matrix = tempMatrix;
    cout<<"Матрица задана\n";
}
 
void printUsualMatrix(const RowFormatMatrix& matrix)
{
    int first,last, num;
 
    vector< vector<double> > usualMatrix(matrix.row,matrix.col);
    for (int i=0; i<matrix.row; i++)
    {
        first = matrix.ia[i];
        last = matrix.ia[i+1];
 
        for (int j=first; j<last; j++)
        {
            num = matrix.ja[j];
            usualMatrix[i][num] = matrix.an[j];
        }
    }
 
    cout.precision(2);
    for (int i=0; i<matrix.row; i++)
    {
        for (int j=0; j<matrix.col; j++)
        { 
            cout.width(5);
            cout<<fixed<<usualMatrix[i][j]<<" ";
        }
        cout<<"\n";
    }
    cout.precision(0);
}
И потом включаю оба хедера и в main и в support.
Могу даже сам проект кинуть http://rghost.ru/45544528
Байт
Эксперт C
15979 / 10247 / 1536
Регистрация: 24.12.2010
Сообщений: 19,327
25.04.2013, 17:50 #9
Цитата Сообщение от UrbanLynx Посмотреть сообщение
Так вот как она попадает во второй файл? Там же защита стоит, он смотрит что этот хедер уже включен и не трогает его больше. Нет?
Защита действует только в пределах одного cpp-файла.
Ты хоть представляешь, как препроцессор работает? Если нет - почитай. Тут на форуме есть хорошая прикрепленная статья от Evg

Добавлено через 2 минуты
http://www.cyberforum.ru/blogs/18334/blog100.html
UrbanLynx
1 / 1 / 0
Регистрация: 13.02.2013
Сообщений: 29
25.04.2013, 18:38  [ТС] #10
Цитата Сообщение от Байт Посмотреть сообщение
Защита действует только в пределах одного cpp-файла.
Вы хотите сказать, что если я подключаю один хедер к нескольким cpp-файлам, то у меня будет ругаться линковщик, потому что один и тот же кусок кода включается более одного раза? Если да, то это бред. Если нет, то я вас не понял.
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
25.04.2013, 18:49 #11
Цитата Сообщение от UrbanLynx Посмотреть сообщение
Вы хотите сказать, что если я подключаю один хедер к нескольким cpp-файлам, то у меня будет ругаться линковщик, потому что один и тот же кусок кода включается более одного раза?
Вопрос некоректен
если у тебя одна и та же функция(переменная) реализована в разных модулях то линковщик будет ругаться и никакие защиты не помогут
поэтому и делают реализацию в С файлах, а в заголовочных только объявление
тогда точно реализация не попадет в другой объектный модуль
если конечно сам не впихаешь
C++
1
#include "My.c"
(иногда встречается )
veverix
39 / 39 / 2
Регистрация: 14.09.2012
Сообщений: 85
25.04.2013, 18:51 #12
SparseMatrix.h:

C++
1
2
3
4
5
6
#ifndef SPARSE
#define SPARSE
 
объявления функций, классов и глобальных переменных
 
#endif
SparseMatrix.cpp:

C++
1
2
3
#include "SparseMatrix.h"
 
определение функций
Проблема решится только разделением на заголовочный файл и .cpp с одним и тем же наименованием.
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
25.04.2013, 18:56 #13
Цитата Сообщение от vxg Посмотреть сообщение
как видим не прекрасно.
что
C++
1
#pragma once
что
C++
1
2
3
4
#ifndef module_name_h
#define module_name_h
//содержимое
#endif
защищают один модуль компиляции
на другие не действует
препроцессор ничего не знает про другие файлы
вот здесь маленкое сравнение
http://ru.wikipedia.org/wiki/Pragma_once

Добавлено через 2 минуты
Цитата Сообщение от veverix Посмотреть сообщение
Проблема решится только разделением на заголовочный файл и .cpp с одним и тем же наименованием.
Это не критично, хотя удобно
Имена могут быть любые
UrbanLynx
1 / 1 / 0
Регистрация: 13.02.2013
Сообщений: 29
25.04.2013, 19:20  [ТС] #14
Ну ок, разделил, все по прежнему
sparseMatrix.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
#ifndef SPARSEMATRIX_H
#define SPARSEMATRIX_H
 
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
 
using namespace std;
 
class RowFormatMatrix
{
public:
    RowFormatMatrix(int c=0, int r=0):col(c),row(r),ia(0),ja(0),an(0){}
    RowFormatMatrix(const vector<int>& i, const vector<int>& j, const vector<double>& n, int c, int r):ia(i),ja(j),an(n),col(c),row(r){}
    ~RowFormatMatrix(){}
 
    friend RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b);
    friend void printUsualMatrix(const RowFormatMatrix& matrix);
    friend void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
    friend void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
protected:
    vector<int> ia; // номер компонента в ja и an, с которого начинается текущая строка
    vector<int> ja; // номера столбцов
    vector<double> an;
    int col, row;
};
 
void symbolicPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
void numericalPart(const RowFormatMatrix& a, const RowFormatMatrix& b, RowFormatMatrix& c);
RowFormatMatrix operator+(const RowFormatMatrix& a, const RowFormatMatrix& b);
void enterUsualMatrix(RowFormatMatrix& matrix);
void enterRowFormatMatrix(RowFormatMatrix& matrix);
void printUsualMatrix(const RowFormatMatrix& matrix);
 
#endif
sparseMatrix.cpp
C++
1
2
3
4
5
6
7
8
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
 
#include "sparseMatrix.h"
 
// реализация функция, объявленных в sparseMatrix.h
Ну и так же везде
C++
1
#include "sparseMatrix.h"
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
25.04.2013, 19:40 #15
UrbanLynx,
взял твой проект но поскольку у мена 2008 то взял только Сишные файлы и заголовки
все прекрасно скомпилировалось
попробуй почистить проект
если нужно могу заслать проект который у меня получился
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.04.2013, 19:40
Привет! Вот еще темы с ответами:

Функция _msize не определена - C++
#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;functional&gt; using namespace std; int getMaxMinElem(int*,bool);//true-&gt;max,...

Поиск в текстовом файле всех слов, заданных в другом текстом файле - C++
Вообщем такое задание: Поиск в текстовом файле всех слов, заданных в другом текстом файле; Не могу понять почему не работает: ...

Сравнение слов в одном файле со словами в другом файле - C++
Здравствуйте! Суть задачи такая: 1. Первый файл - запросы с городами, второй файл - база городов РФ. Оба txt 2. Найти в запросах все...

Ошибка: error C2129: статическая функция объявлена, но не определена - C++
В помощь начинающим изучать C++ хочу подсказать реальную причину этой ошибки. Так как реально в интернете на форумах рассказывается...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
25.04.2013, 19:40
Ответ Создать тему
Опции темы

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