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

Как правильно вызывать функцию объекта из другой функции того же объекта? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Negent
 Аватар для Negent
9 / 9 / 1
Регистрация: 01.11.2011
Сообщений: 21
07.12.2011, 02:39     Как правильно вызывать функцию объекта из другой функции того же объекта? #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
void ClassName::authentication ()
        {
            int tempPass;
            int password = 1234;
            int pin = 4321;
            cout<<"Procedure authentication!\n"
                <<"Please enter password ("<<password<<"): ";
            cin>>tempPass;
            if (tempPass == password)
                {
                    cout<<"You can enter information\n";
                    ClassName::setData ();
                }
            if (tempPass == pin)
                {
                    cout<<"You can get information\n";
                    ClassName::getData ();
                }
            else
                {
                    cout<<"Sorry, you not passed authentication...\n"
                        <<"Please, run program again!\n";
                }
        }
В зависимости от введённого пароля будет вызываться функция редактирования данных (администраторский пароль) или функция выдачи результата (пользовательский pin-код).

Привожу текст всех трёх файлов, составляющих программу на C/C++:

Файл, содержащий описания функций:
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
#include "stdafx.h"
#include "BankClass.h"
 
#include <iostream>
#include <iomanip>
 
#include <string>
 
using namespace std;
 
    ClassName::ClassName ()
        {
            nameOfUser = 'anonymous';
            accountNumber = 0000;
            initialBalance = 0;
            sumIncome = 0;
            sumExpense = 0;
            currentBalance = 0;
            creditLimit = 100;
            maximumSum = 0;
        }
    void ClassName::authentication ()
        {
            int tempPass;
            int password = 1234;
            int pin = 4321;
            cout<<"Procedure authentication!\n"
                <<"Please enter password ("<<password<<"): ";
            cin>>tempPass;
            if (tempPass == password)
                {
                    cout<<"You can enter information\n";
                    ClassName::setData ();
                }
            if (tempPass == pin)
                {
                    cout<<"You can get information\n";
                    ClassName::getData ();
                }
            else
                {
                    cout<<"Sorry, you not passed authentication...\n"
                        <<"Please, run program again!\n";
                }
        }
    void ClassName::setData ()
        {
            cout<<"Name: ?\b";
            getline (cin, nameOfUser);
            cout<<"Number of account: ?\b";
            cin>>accountNumber;
            cout<<"Initial balance: ?\b";
            cin>>initialBalance;
            cout<<"Income sum: ?\b";
            cin>>sumIncome;
            cout<<"Expense sum: ?\b";
            cin>>sumExpense;
        }
    void ClassName::getData ()
        {
            cout<<"Name: "<<nameOfUser<<endl;
            cout<<"Number of account: "<<accountNumber<<endl;
            cout<<"Initial balance: "<<initialBalance<<endl;
            cout<<"Income sum: "<<sumIncome<<endl;
            cout<<"Expense sum: "<<sumExpense<<endl;
            currentBalance = initialBalance + sumIncome - sumExpense;
            cout<<"Current balance: "<<currentBalance<<endl;
            maximumSum = currentBalance + creditLimit;
            cout<<"Maximum sum: "<<maximumSum<<endl;
        }
Файл, содержащий прототипы функций:
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
#include "stdafx.h"
 
#include <iostream>
#include <iomanip>
 
#include <string>
 
using namespace std;
 
class ClassName
    {
    public:
        ClassName::ClassName ();
        void ClassName::authentication (); //Функция проведения аутентификации
        void ClassName::setData (); //Функция установки значений
        void ClassName::getData (); //Функция получения и вычисления значений
    private:
        string ClassName::nameOfUser; //Имя владельца счёта
        int ClassName::accountNumber; //Номер счёта
        int ClassName::initialBalance; //Начальный баланс (денег на счету)
        int ClassName::sumIncome; //Количество входящих платежей
        int ClassName::sumExpense; //Количество исходящих платежей
        int ClassName::currentBalance; //Настоящий (текущий) баланс
        int ClassName::creditLimit; //Размер максимального кредита, при нулевом балансе на счету
        int ClassName::maximumSum; //Размер максимального кредита, при текущем балансе на счету
    };
Файл, содержащий исполняемый код (создание объекта, вызов конструктора и т.д.):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Bankomat.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "BankClass.h"
 
#include <iostream>
#include <iomanip>
 
#include <string>
 
using namespace std;
 
ClassName ClassObject;
 
void main ()
{
    cout<<"Hello, programmer!\n";
    ClassObject.authentication ();
    ClassObject.authentication ();
    cout<<"Done!\n";
    system ("pause");
}
Как я понял, моя ошибка заключается в неправильном вызове функций из другой функции того же объекта. Из конструктора можно производить вызов (проверено экспериментально). Подскажите, что мне делать: вызов только через конструктор или есть какая-то хитрость?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.12.2011, 02:39     Как правильно вызывать функцию объекта из другой функции того же объекта?
Посмотрите здесь:

C++ Требуется ли при удалении объекта посредством delete указывать тип объекта?
При возврате объекта из функции пишет, что для объекта не определен констуктор копирования C++
C++ Как правильно вызывать функцию strcmp()?
Как создать отдельную функцию для каждого объекта класса C++
Создание объекта в функции и возврат объекта из нее C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bers
Заблокирован
07.12.2011, 02:50     Как правильно вызывать функцию объекта из другой функции того же объекта? #2
Цитата Сообщение от Negent Посмотреть сообщение
Как я понял, моя ошибка заключается в неправильном вызове функций из другой функции того же объекта. Из конструктора можно производить вызов (проверено экспериментально). Подскажите, что мне делать: вызов только через конструктор или есть какая-то хитрость?
Внутри одного метода всегда можно вызвать любой другой метод класса.
Negent
 Аватар для Negent
9 / 9 / 1
Регистрация: 01.11.2011
Сообщений: 21
07.12.2011, 02:53  [ТС]     Как правильно вызывать функцию объекта из другой функции того же объекта? #3
Цитата Сообщение от Bers Посмотреть сообщение
Внутри одного метода всегда можно вызвать любой другой метод класса.
Так-с... Значит, ошибка в чём-то другом.
Одну я уже нашёл: присваивание строкового значения выполняется парой двойных кавычек "", у меня же используются пара одинарных.
Но программа всё равно не работает.
Bers
Заблокирован
07.12.2011, 02:57     Как правильно вызывать функцию объекта из другой функции того же объекта? #4
Цитата Сообщение от Negent Посмотреть сообщение
Но программа всё равно не работает.
1. Работает, но делает не то что надо. (описание неисправности)

2. Крошится в рантайме, под ругательства системы. (скриншот, или примерное описание текста сообщение системы)

3. Не компилируется. (Точный текст ошибки компилятора. Желательно - с указанием точных строчек кода, на которые ругнулся компилятор)

4. Не компонуется. (Точный текст ошибки компоновщика.)

Телепаты в отпуске.
Negent
 Аватар для Negent
9 / 9 / 1
Регистрация: 01.11.2011
Сообщений: 21
07.12.2011, 03:14  [ТС]     Как правильно вызывать функцию объекта из другой функции того же объекта? #5
Цитата Сообщение от Bers Посмотреть сообщение
1. Работает, но делает не то что надо. (описание неисправности)

2. Крошится в рантайме, под ругательства системы. (скриншот, или примерное описание текста сообщение системы)

3. Не компилируется. (Точный текст ошибки компилятора. Желательно - с указанием точных строчек кода, на которые ругнулся компилятор)

4. Не компонуется. (Точный текст ошибки компоновщика.)

Телепаты в отпуске.
Вот что мне пишет MS VS 2008:

1>------ Build started: Project: Bankomat, Configuration: Debug Win32 ------
1>Compiling...
1>BankClass.cpp
1>c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\bankclass.cpp(1) : error C2471: cannot update program database 'c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\debug\vc90.pdb'
1>c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\bankclass.cpp(1) : fatal error C1083: Cannot open program database file: 'c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\debug\vc90.pdb': No such file or directory
1>Bankomat.cpp
1>c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\bankomat.cpp(3) : error C2471: cannot update program database 'c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\debug\vc90.pdb'
1>c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\bankomat.cpp(3) : fatal error C1083: Cannot open program database file: 'c:\users\negent\documents\visual studio 2008\projects\bankomat\bankomat\debug\vc90.pdb': No such file or directory
1>Generating Code...
1>Build log was saved at "file://c:\Users\Negent\Documents\Visual Studio 2008\Projects\Bankomat\Bankomat\Debug\BuildLog.htm"
1>Bankomat - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Компилятор ругается на строчки #include "stdafx.h", в обоих файлах *.cpp
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
07.12.2011, 03:29     Как правильно вызывать функцию объекта из другой функции того же объекта? #6
Цитата Сообщение от Negent Посмотреть сообщение
Компилятор ругается на строчки #include "stdafx.h", в обоих файлах *.cpp
проект нужно создавать пустой
Цитата Сообщение от Negent Посмотреть сообщение
void main ()
Цитата Сообщение от Negent Посмотреть сообщение
public: ClassName::ClassName ();
а так писать вас Дейтейл "научил" ?
Negent
 Аватар для Negent
9 / 9 / 1
Регистрация: 01.11.2011
Сообщений: 21
07.12.2011, 03:33  [ТС]     Как правильно вызывать функцию объекта из другой функции того же объекта? #7
А что тут неправильно написано?
В разделе "public", объявлен конструктор, у которого стоит адресация - :: на класс с именем ClassName. Да, примерно так у Дейтела записано:
ClassName::ClassName ();
Bers
Заблокирован
07.12.2011, 03:36     Как правильно вызывать функцию объекта из другой функции того же объекта? #8
Цитата Сообщение от Negent Посмотреть сообщение
ClassName::ClassName ();
Это разрешение контекста. Вещь хорошая.
Но в вашем случае можно писать попроще и покороче:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class ClassName
        {
        public:
                ClassName ();
                void authentication (); //Функция проведения аутентификации
                void setData (); //Функция установки значений
                void getData (); //Функция получения и вычисления значений
        private:
                string nameOfUser; //Имя владельца счёта
        int accountNumber; //Номер счёта
        int initialBalance; //Начальный баланс (денег на счету)
        int sumIncome; //Количество входящих платежей
        int sumExpense; //Количество исходящих платежей
                int currentBalance; //Настоящий (текущий) баланс
                int creditLimit; //Размер максимального кредита, при нулевом балансе на счету
                int maximumSum; //Размер максимального кредита, при текущем балансе на счету
        };
Negent
 Аватар для Negent
9 / 9 / 1
Регистрация: 01.11.2011
Сообщений: 21
07.12.2011, 04:29  [ТС]     Как правильно вызывать функцию объекта из другой функции того же объекта? #9
Цитата Сообщение от Bers Посмотреть сообщение
Это разрешение контекста. Вещь хорошая.
Но в вашем случае можно писать попроще и покороче:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class ClassName
        {
        public:
                ClassName ();
                void authentication (); //Функция проведения аутентификации
                void setData (); //Функция установки значений
                void getData (); //Функция получения и вычисления значений
        private:
                string nameOfUser; //Имя владельца счёта
        int accountNumber; //Номер счёта
        int initialBalance; //Начальный баланс (денег на счету)
        int sumIncome; //Количество входящих платежей
        int sumExpense; //Количество исходящих платежей
                int currentBalance; //Настоящий (текущий) баланс
                int creditLimit; //Размер максимального кредита, при нулевом балансе на счету
                int maximumSum; //Размер максимального кредита, при текущем балансе на счету
        };
Первое. Проверил - программа работает без операции разрешения контекста. Здорово! Огромное спасибо!
Второе. Если пересоздать программу в пустом проекте - всё работает. Отлично!

Проблема решена. Всем спасибо!

Добавлено через 46 минут
Хочется привести полный текст программы с исправленными недостатками и замечаниями.
После отладки, программа приобрела новые качества, в том числе, укорачивать вводимое имя.

Точка входа, файл "Bankomat_2.cpp":
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Bankomat_2.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include "BankClass.h"
 
#include <iostream>
#include <iomanip>
 
#include <string>
 
using namespace std;
 
void main ()
{
    cout<<"Hello, programmer!\n";
    ClassName ClassObject;
    ClassObject.authentication ();
    ClassObject.authentication ();
    cout<<"Done!\n";
    system ("pause");
}
Заголовочный файл "BankClass.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
#include "stdafx.h"
 
#include <iostream>
#include <iomanip>
 
#include <string>
 
using namespace std;
 
class ClassName
    {
    public:
        ClassName::ClassName ();
        void ClassName::authentication ();
        void ClassName::setData (); //Функция установки значений
        void ClassName::getData (); //Функция получения и вычисления значений
    private:
        string ClassName::nameOfUser; //Имя пользователя
                int ClassName::accountNumber; //Номер счёта
                int ClassName::initialBalance; //Начальный баланс (денег на счету)
                int ClassName::sumIncome; //Количество входящих платежей
                int ClassName::sumExpense; //Количество исходящих платежей
        int ClassName::currentBalance; //Настоящий (текущий) баланс
        int ClassName::creditLimit; //Размер максимального кредита, при нулевом балансе на счету
        int ClassName::maximumSum; //Размер максимального кредита, при текущем балансе на счету
    };
Файл "BankClass.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
#include "stdafx.h"
#include "BankClass.h"
 
#include <iostream>
#include <iomanip>
 
#include <string>
 
using namespace std;
 
    ClassName::ClassName ()
        {
            nameOfUser = "anonymous";
            accountNumber = 0000;
            initialBalance = 0;
            sumIncome = 0;
            sumExpense = 0;
            currentBalance = 0;
            creditLimit = 100;
            maximumSum = 0;
        }
    void ClassName::authentication ()
        {
            int tempPass;
            int password = 1234; //Пароль для редактирования данных
            int pin = 4321; //Пароль для вывода данных и результатов
            cout<<"Procedure authentication!\n"
                <<"Please enter password ("<<pin<<"): ";
            cin>>tempPass;
            if (tempPass == password)
                {
                    cout<<"You can enter information"<<endl;
                    ClassName::setData ();
                }
            else if (tempPass == pin)
                {
                    cout<<"You can get information"<<endl;
                    ClassName::getData ();
                }
            else
                {
                    cout<<"Sorry, you not passed authentication\n"
                        <<"Please, run program again!"<<endl;
                };
        }
    void ClassName::setData ()
        {
            cout<<"Name of user: ?\b";
            cin.get (); //Для извлечения разделителя новой строки - иначе, getline не считает вводимое имя
            getline (cin,nameOfUser);
            if (nameOfUser.length () > 20) 
            {
                cout<<"Too long!\n"<<"Cut from 20-symbol\n";
                nameOfUser = nameOfUser.substr (0, 20); //Обрезаем имя пользователя до 20 символов
                cout<<"New name: "<<nameOfUser<<endl;
            }
            cout<<"Number of account: ?\b";
            cin>>accountNumber;
            cout<<"Initial balance: ?\b";
            cin>>initialBalance;
            cout<<"Income sum: ?\b";
            cin>>sumIncome;
            cout<<"Expense sum: ?\b";
            cin>>sumExpense;
        }
    void ClassName::getData ()
        {
            cout<<"Name of user: "<<nameOfUser<<endl;
            cout<<"Number of account: "<<accountNumber<<endl;
            cout<<"Initial balance: "<<initialBalance<<endl;
            cout<<"Income sum: "<<sumIncome<<endl;
            cout<<"Expense sum: "<<sumExpense<<endl;
            currentBalance = initialBalance + sumIncome - sumExpense;
            cout<<"Current balance: "<<currentBalance<<endl;
            maximumSum = currentBalance + creditLimit;
            cout<<"Maximum sum: "<<maximumSum<<endl;
        }
Эти тексты приведены на случай, если кто-то воспользуется поиском по интернету для решения задач из Дейтела.
P. S. Процедуру разрешения контекста я оставил. Дейтелы её дают - профессорам виднее.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
07.12.2011, 06:18     Как правильно вызывать функцию объекта из другой функции того же объекта? #10
Цитата Сообщение от Negent Посмотреть сообщение
P. S. Процедуру разрешения контекста я оставил. Дейтелы её дают - профессорам виднее.
Странно как то, вроде о Дейтлах хорошие отзывы пишут, поэтму думаю, если у них так написанно, то есть объяснение этому. В данном случае так (как в листинге BankClass.h) писать не нужно, это только увеличивает код, а практической пользы = 0
greeezz
07.12.2011, 06:36
  #11

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
Странно как то, вроде о Дейтлах хорошие отзывы пишут, поэтму думаю, если у них так написанно, то есть объяснение этому.
Цитата Сообщение от Negent Посмотреть сообщение
... Да, примерно так у Дейтела записано:
ClassName::ClassName ();
В том то и дело что примерно. не в одном из Software Engineering Case Study "ATM System" я не нашел ни одного примера где используется разрешение контектса а объявлении классов. Есть использование только в имплементации классов.

Bers
Заблокирован
07.12.2011, 07:31     Как правильно вызывать функцию объекта из другой функции того же объекта? #12
Цитата Сообщение от greeezz Посмотреть сообщение
я не нашел ни одного примера где используется разрешение контектса а объявлении классов.
Ну вот например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Base {  void View() { std::cout<< "Base\n"; } };
struct Next: protected Base 
{  
    void View(int v) { std::cout<< "Next\n"; } 
    Base::View;  //методы базового типа 
                 //вообще то protected в наследнике.
                 //хотя вообще то, дабы не смущать общественность
                //лучше перед разрешением контекста в объявлении
                 //ставить ключевое слово using
};
 
 
int main()
{
    Next test; 
    test.View(); //наследник вызывает "разрешенный" 
                     //protected метод своего предка
    test.View(1);
}
Добавлено через 13 минут
и ещё для наглядности вот:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Base {  protected: void View() { std::cout<< "Base\n"; } };
struct Next: protected Base 
{  
    void View(int v) { std::cout<< "Next\n"; } 
    using Base::View;  //обрати внимание, в базовом классе
                       //метод находится в protected зоне
};
 
 
int main()
{
    Next test; 
    test.View(); //однако мы указали компилятору, 
                 //что для наследника, методы
                 //находятся в зоне модификаторов
                 //доступа наследника
    test.View(1);
}
Ну и напоследок:

C++
1
2
3
4
5
6
struct Base { private: void View() { std::cout<< "Base\n"; } };
struct Next: protected Base 
{  
    void View(int v) { std::cout<< "Next\n"; } 
    using Base::View;  // error C2876: Base: не все перегрузки доступны
};
К приватным методам-данным наследник доступа не имеет. Инкапсуляция
Negent
 Аватар для Negent
9 / 9 / 1
Регистрация: 01.11.2011
Сообщений: 21
07.12.2011, 09:43  [ТС]     Как правильно вызывать функцию объекта из другой функции того же объекта? #13
Цитата Сообщение от Kastaneda Посмотреть сообщение
Странно как то, вроде о Дейтлах хорошие отзывы пишут, поэтму думаю, если у них так написанно, то есть объяснение этому. В данном случае так (как в листинге BankClass.h) писать не нужно, это только увеличивает код, а практической пользы = 0
Может быть, они потом (далее, в книге) расширяют объяснения и показывают, зачем нужна эта операция. Но пока что, я не знаю зачем...
greeezz
07.12.2011, 16:12
  #14

Не по теме:

Цитата Сообщение от Bers Посмотреть сообщение
Ну вот например:
не выдергивайте куски из контекста. речь шла не о переиспользовании функций базового класса а о вот таком объявлении класса :
C++
1
2
3
4
5
6
7
8
9
10
 ...... 
public:
                ClassName::ClassName ();
                void ClassName::authentication (); //Функция проведения аутентификации
                ........
private:
        string ClassName::nameOfUser; //Имя владельца счёта
        int ClassName::accountNumber; //Номер счёта
       ..........................
};

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.12.2011, 17:12     Как правильно вызывать функцию объекта из другой функции того же объекта?
Еще ссылки по теме:

C++ Зачем в программе 2 раза вызывать конструктор для одного объекта
C++ Как вызвать другой конструктор для уже созданного объекта конструктором по умолчанию?
Как передать адрес объекта через функцию C++

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

Или воспользуйтесь поиском по форуму:
Bers
Заблокирован
07.12.2011, 17:12     Как правильно вызывать функцию объекта из другой функции того же объекта? #15
Цитата Сообщение от greeezz Посмотреть сообщение
не выдергивайте куски из контекста.
Так в заявленном контексте речь шла о разрешении котенкста)))

Цитата Сообщение от greeezz Посмотреть сообщение
я не нашел ни одного примера где используется разрешение контектса а объявлении классов.
Что до ТС, то учитывая, что он единственный из всей толпы, кто учась по Дейтлам принял манеру так писать, то скорее всего он не правильно понял о чем пишет автор учебника))
Yandex
Объявления
07.12.2011, 17:12     Как правильно вызывать функцию объекта из другой функции того же объекта?
Ответ Создать тему
Опции темы

Текущее время: 09:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru