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

Ультиматум варнинга - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Капитан Техно
 Аватар для Капитан Техно
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 32
21.02.2012, 13:55     Ультиматум варнинга #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
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
#include <iostream>
#include <pthread.h>
#include <unistd.h>
 
class Time{
public:
   Time(int = 8, int = 0, int = 0);
   void setTime(int, int, int);
 
   //запуск часов
   void runTime();
   //печать текущего состояния часов
   void printMilitary();
 
private:
   int hour;   // час
   int minute; //минуты
   int second; //секунды
};
 
using namespace std;
 
Time::Time(int hr, int min, int sec)
{ setTime(hr, min, sec); }
 
 void Time::setTime(int h, int m, int s)
{
    hour = (h > 0 && h < 24) ? h : 0;
    minute = (m > 0 && m < 60) ? m : 0;
    second = (s > 0 && s < 60) ? s : 0;
}
 
void Time::runTime()
{
   while(hour != 18)
   {
      usleep(1000000);
      if(second < 59)
       { second++; }
      else if(second == 59)
       {
        second = 0;
        minute++;
 
         if(minute < 59)
          { minute++; }
          else if(minute == 59)
          {
            minute = 0;
            hour++;
 
            if(hour < 24 && hour != 24)
             { hour++; }
            else
              { hour = 0; }
          }
 
       }
 
 
   printMilitary();
 
   }
   pthread_exit(NULL);
}
 
 void Time::printMilitary()
{
    cout << (hour < 10 ? "0" : "") << hour << ":"
         << (minute < 10 ? "0" : "") << minute << ":"
         << (second < 10 ? "0" : "")<< second << endl;
}
 
int main()
{
    cout << "Hello world!!!"
         << "Демонстрация работы функции времени: " << endl;
 
   
    pthread_t t1;
    int check;
 
    check = pthread_create(&t1, NULL, (void *(*)(void *))&Time::runTime, NULL);
 
 
 
 
    return 0;
}
сабж:

Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:86:65: error: converting from 'void (Time::*)()' to 'void* (*)(void*)' [-pedantic]
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2012, 13:55     Ультиматум варнинга
Посмотрите здесь:

Почему нет варнинга на использование неиниц. переменной? C++
Windows XP Где скачать надежную ОС xp sp3 ультиматум 2010
Википедия, Ультиматум, Пиратство

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
21.02.2012, 13:59     Ультиматум варнинга #2
Похоже, что ты пытаешься сконвертить указатель на метод в указатель на функцию.
Это - не получится никак - это совершенно разные и неприводимые друг к другу типы.
У метода есть скрытый параметр this.
Капитан Техно
 Аватар для Капитан Техно
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 32
21.02.2012, 14:01  [ТС]     Ультиматум варнинга #3
быть может этот this можно как то направить в правильное русло? или легче какой то другой модуль программы вывести в отдельный поток?
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
21.02.2012, 14:10     Ультиматум варнинга #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Вот для начала почитай.


Указатели на функции и указатели на методы

Есть еще одна, более важная причина, по которой нельзя считать нашу функцию-фильтр copy_if() достаточно универсальной: мы не можем передать функции-фильтру предикат-метод. Дело в том, что указатель на метод существенно отличается по типу от обычного указателя на функцию, даже если прототипы функции и метода внешне идентичны. Вспомним, как определяется указатель на функцию:
Javascript
1
тип (*имя-указателя)(список параметров);
Для сокращения записи применяют обычно оператор typedef. Следующее объявление вводит новое имя типа:
Javascript
1
typedef тип (*тип-указателя)(список параметров);
После этого указатель на функцию можно объявлять так:
Delphi
1
тип-указателя имя-указателя;
Указателю присваивается адрес функции. В С++ разрешается присваивать адрес функции явно или неявно задавая операцию получения адреса:
Delphi
1
2
имя-указателя = &имя-функции;
имя-указателя = имя-функции;
В последнем случае имя функции неявно преобразуется в адрес.
ПРИМЕЧАНИЕ
В системе Visual C++.NET 2003 для библиотечных функций работает только вариант с явной операцией адресации. Второй вариант вызвал фатальную ошибку компилятора fatal error 1001: INTERNAL COMPILER ERROR. Borland C++ Builder 6 оба вызова обрабатывает правильно.

Вызов функции через указатель выполняется так:
Javascript
1
(*имя-указателя)(аргументы);
Тот же вызов можно написать в более простой форме:
и
Javascript
1
мя-указателя(аргументы);
Рассмотрим несколько простых примеров. Допустим, у нас объявлен указатель на функцию:
Javascript
1
int (*pf)(void);
Этому указателю можно присвоить адрес любой функции с таким же прототипом, в том числе и библиотечной. Например, такой прототип имеет функция-генератор случайного числа rand(), который объявлен в заголовке библиотеки <cstdlib>:
Javascript
1
2
3
4
5
int f1(void) { return 1; } 
int f2(void) { return 2; }
pf = f1;    cout << pf() << endl;                // вызов f1()
pf = f2;    cout << pf() << endl;                // вызов f2()
pf = &rand; cout << pf() << endl;                // вызов rand()
Напишем теперь простой класс
Javascript
1
2
3
4
5
6
class Constant
{    int value;
   public: 
    Constant(const int &a): value(a) {}
    int get(void) { return value; }
};
Метод get() с виду имеет тот же прототип, что и функции в приведенном ранее фрагменте. Однако попытки присвоить адрес метода get() указателю pf компилятор пресекает «на корню». Да и не совсем понятно, как этот адрес задавать. Вариантов два.
  1. Объявить объект и взять адрес метода в объекте:
    Constant A(5); pf = &A.get();
  2. Не объявлять объект, а приписать префикс класса:
    pf = &Constant::get;
Первый вариант вообще неверный: и Visual C++.NET 2003, и Borland C++ Builder 6 сообщают, что операцию взятия адреса & так использовать нельзя. Второй вариант — ближе к истине: оба компилятора сообщают только о невозможности выполнить преобразование типов. Попытки прописать преобразование явно не проходят:
Javascript
1
2
3
pf = static_cast<int (*)(void)>(&Constant::get);
pf = reinterpret_cast<int (*)(void)>(&Constant::get); 
pf = (int (*)(void))(&Constant::get);
Все эти варианты вызывают ту же ошибку компиляции — невозможность преобразования типов. Таким образом, тип указателя на метод класса кардинально отличается от типа указателя на функцию: адрес метода нельзя присвоить указателю на функцию, даже если внешне их прототипы совпадают.
Это становится понятным, если мы вспомнить, что нестатические методы получают дополнительный параметр — указатель this.

Аналогично, нельзя присвоить обычному указателю на функцию адрес виртуального метода — в этом случае дело усугубляется еще наличием в составе объекта указателя на таблицу виртуальных методов. А вот со статическими методами картина другая! Статический метод не получает никаких «лишних параметров», поэтому его адрес можно присваивать обычному указателю на функцию без всяких преобразований. Добавим в класс Constant статическое поле и статический метод с нужным нам прототипом:
Javascript
1
2
3
4
5
6
7
8
class Constant
{    int value;
    static int d;
public: 
    Constant(const int &a): value(a) {}
    int get(void) { return value; }
    static int getd(void) { return d; }                // статический метод
};
Тогда нашему указателю pf можно присвоить адрес статического метода согласно второму из приведенных ранее вариантов, например:
Javascript
1
pf = Constant::getd;        // или pf = &Constant::getd;
Префикс, естественно, необходимо писать.
Указатель на метод объявляется по-другому (см. п.п. 8.3.3 в [1]) — нужно задать имя класса в качестве префикса:
Javascript
1
int (Constant::*pm)(void);
Такому указателю можно присваивать адреса обычных и виртуальных методов согласно второму из приведенных ранее вариантов, например:
Javascript
1
pm = &Constant::get;        // или pm = Constant::get;
Адрес статического метода, так же как и адрес обычной функции, такому указателю присвоить нельзя — возникает ошибка трансляции: компилятор сообщает о невозможности выполнить преобразование типов.
И косвенный вызов метода выполняется по-другому — с помощью операции выбора члена класса .* или ->* (см. п. 5.5 в [1]). Несмотря на то, что указатель на член класса является отдельной независимой от класса переменной, вызов метода по указателю возможен только при наличии объекта, например:
Javascript
1
2
Constant A(5);
cout << (A.*pm)() << endl;
Выражение(A.*pm)() означает следующее: для объекта A вызвать метод, чей адрес записан в указателе pm. Слева от операции .* — объект, справа — указатель на метод. Скобки вокруг выражения A.*pm писать обязательно, так как приоритет операции вызова функции (()) выше, чем приоритет операции выбора члена класса (.*).
В выражении (объект.*указатель) можно заменить часть объект. записью указатель->, например:
Javascript
1
2
Constant *pc = new Constant(7);
cout << (pc->*pm)() << endl;
Обратите внимание: в выражении (pc->*pm) слева — обычный указатель на динамический объект, а справа — указатель на метод этого объекта. Это два совершенно разных типа указателя.
Интересно, что в Visual C++.NET 2003 размер sizeof(pf) указателя на функцию совпадает с размером sizeof(pm) указателя на член класса и равен 4 байта. А вот система Borland C++ Builder 6 выдает совершенно разные цифры: размер указателя на функцию равен 4 байта, а размер указателя на метод — 12 байт!

Почему-то вместо тега С++ код вставляется в тег JS
-=ЮрА=-
Заблокирован
Автор FAQ
21.02.2012, 14:49     Ультиматум варнинга #5
При желании всё можно реализовать

Time.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
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
#include <iostream>
#include <windows.h>
using namespace std;
 
class Time
{
private:
   int hour;   // Г·Г*Г±
   int minute; //ìèГ*ГіГІГ»
   int second; //Г±ГҐГЄГіГ*äû
public:
   Time(int = 8, int = 0, int = 0);
   void setTime(int, int, int);
   //Г§Г*ГЇГіГ±ГЄ Г·Г*ñîâ
   void runTime();
   //ГЇГҐГ·Г*ГІГј ГІГҐГЄГіГ№ГҐГЈГ® ñîñòîÿГ*ГЁГї Г·Г*ñîâ
   void printMilitary();
};
 
using namespace std;
 
Time::Time(int hr, int min, int sec)
{ 
    setTime(hr, min, sec); 
}
 
void Time::setTime(int h, int m, int s)
{
    hour    = (h > 0 && h < 24) ? h : 0;
    minute  = (m > 0 && m < 60) ? m : 0;
    second  = (s > 0 && s < 60) ? s : 0;
}
 
void Time::printMilitary()
{
    cout << (hour   < 10 ? "0" : "") << hour << ":"
         << (minute < 10 ? "0" : "") << minute << ":"
         << (second < 10 ? "0" : "") << second << endl;
}
 
void Time::runTime()
{
    while(hour != 18)
    {
        if(hour < 24 && minute == 59 && second == 59)
            hour++;
        if(hour == 24)
            hour = 0;
        if(second < 59)
            second++;
        if(second == 59) 
        {
            second = 0;
            minute++;
        }
        if(minute < 59 && second == 0)
            minute++;
        if(minute == 59) 
        {
            minute = 0;
            hour++;
        }
        printMilitary();
        Sleep(1000);
        system("cls");
    }
}


threads.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "Time.h"
#include <process.h>
 
void thread(void * param)
{
    Time *ptr = (Time *)param;
    while(true)
        ptr->runTime();
    _endthread();
}
 
int main()
{
    cout<<"Time demonstration\n";
    Time *lpTime = new Time();
    _beginthread(thread,0,(void *)lpTime);
    system("pause");
    return 0;
}

PS: писал под Windows...
Миниатюры
Ультиматум варнинга   Ультиматум варнинга  
Вложения
Тип файла: rar threads.exe.rar (43.6 Кб, 5 просмотров)
Тип файла: rar threads_VS6.0_proj.rar (7.6 Кб, 5 просмотров)
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
21.02.2012, 17:33     Ультиматум варнинга #6
В потоке нельзя вызвать отдельно метод. Правильно было бы в потоке вызвать обычную функцию, дотащив до туда экземпляр класса (через параметр), а в функции через этот экхемпляр вызвать метод
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
21.02.2012, 17:37     Ультиматум варнинга #7
если нужно передать указатель на метод без привязки к объекту, очевидно, метод должен быть статическим
-=ЮрА=-
Заблокирован
Автор FAQ
21.02.2012, 17:40     Ультиматум варнинга #8
Цитата Сообщение от Evg Посмотреть сообщение
В потоке нельзя вызвать отдельно метод. Правильно было бы в потоке вызвать обычную функцию, дотащив до туда экземпляр класса (через параметр), а в функции через этот экхемпляр вызвать метод
Evg, я так и сделал
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
void thread(void * param)
{
* * * * Time *ptr = (Time *)param;
* * * * while(true)
* * * * * * * * ptr->runTime();
* * * * _endthread();
}
int main()
{
* * * * cout<<"Time demonstration\n";
* * * * Time *lpTime = new Time();
* * * * _beginthread(thread,0,(void *)lpTime);
* * * * system("pause");
* * * * return 0;
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
21.02.2012, 17:44     Ультиматум варнинга #9
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Evg, я так и сделал
Я просто словами объяснил, шоб понятнее было
-=ЮрА=-
Заблокирован
Автор FAQ
21.02.2012, 17:46     Ультиматум варнинга #10
Цитата Сообщение от Evg Посмотреть сообщение
Я просто словами объяснил, шоб понятнее было
- аааа
Капитан Техно
 Аватар для Капитан Техно
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 32
21.02.2012, 20:05  [ТС]     Ультиматум варнинга #11
-=ЮрА=-, переделал под свой линух, беда, не правильно работает. Походу легче создать поток для другой части своей программы, и вообще почитать про процессы.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
21.02.2012, 20:07     Ультиматум варнинга #12
Цитата Сообщение от Капитан Техно Посмотреть сообщение
-=ЮрА=-, переделал под свой линух, беда, не правильно работает.
Так ты покажи, что там натворил
Капитан Техно
 Аватар для Капитан Техно
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 32
21.02.2012, 20:29  [ТС]     Ультиматум варнинга #13
да вообще так накакал)
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
#include <iostream>
#include <pthread.h>
#include "time.h"
 
using namespace std;
 
 void thread(void * param)
{
    Time *ptr = (Time *) param;
 
     ptr->runTime();
 
    pthread_exit(NULL);
 
}
 
int main()
{
    cout << "Hello world!!!"
         << "Демонстрация работы функции времени: " << endl;
 
 
    pthread_t t1;
    int check;
 
    
 
    check = pthread_create(&t1, NULL, (void *(*)(void *))&thread, NULL);
 
    if(check == 0)
      cout << "Первый поток успешно создан лол!" << endl;
    else
      cout << "Хрень какая то";
 
 
 
 
 
 
    return 0;
}
Одного не пойму зачем в примере Юрия.
C++
1
Time *lpTime = new Time();
В общем программа выполняется, но метод не приходит в действие. только фраза "Первый поток успешно создан лол!" и все, завершение программы
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
21.02.2012, 20:37     Ультиматум варнинга #14
Ну естественно. Как только завершилась основная программа, её потоки умирают вместе с программой. Ты словами-то объясни, что в конечном итоге хочешь видеть?
Капитан Техно
 Аватар для Капитан Техно
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 32
21.02.2012, 20:44  [ТС]     Ультиматум варнинга #15
Хочу что бы время тикало в отдельном потоке, а потом опираясь на эти данные выполнять другие операции
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
21.02.2012, 20:47     Ультиматум варнинга #16
C++
1
2
3
4
5
6
7
8
9
10
    check = pthread_create(&t1, NULL, (void *(*)(void *))&thread, NULL);
 
    if(check == 0)
      cout << "Первый поток успешно создан лол!" << endl;
    else
      cout << "Хрень какая то";
    
    //теперь ждем завершения потока
   
    pthread_join (t1, NULL);
Добавлено через 2 минуты
лучше даже так
C++
1
2
3
4
    if(check == 0)
      cout << "Первый поток успешно создан лол!" << endl;
    else
      cout << strerror(check);
Капитан Техно
 Аватар для Капитан Техно
0 / 0 / 0
Регистрация: 18.07.2011
Сообщений: 32
21.02.2012, 20:49  [ТС]     Ультиматум варнинга #17
О ГОСПОДИ!!! Аллилуйя! It's worked! Спасибо!!! А для меня печальный опыт, больше чтения, меньше страдания фигнёй. Спасибо всем кто участвовал в дискусии. Kastaneda отдельное спасибо, жаль что под вашим постом не отображается кнопка сказать спасибо, не могу плюсануть.
Yandex
Объявления
21.02.2012, 20:49     Ультиматум варнинга
Ответ Создать тему
Опции темы

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