Этот человек кажется, что неправильно понял понятие программирования к интерфейсу. Это не относится к программированию использования только interface
ключевое слово в .Net/Java или классе с только чистыми виртуальными функциями в C++, интерфейс, которые упомянуты в том принципе, является высокоуровневой конструкцией, которая инкапсулирует низкого уровня системы. Как с умножением, это инкапсулирует идею добавить число к себе определенное количество повторений. Но когда мы говорим 3 * 2, мы не заботимся, ли это 3 + 3, 2 + 2 + 2 или (2 + 2) + 2, где часть в круглых скобках кэшируется. Пока мы получаем 6 от него.
, На самом деле, понятие интерфейсов может быть заполнено interface
или abstract class
или комбинация их, как имеет место со многими шаблонами GoF. Это просто что interface
вид ключевого слова облаков вода с неоднозначностью.
Это забавно. Вид этого парня взглядов, вероятно, что породило комментарии, такие как те центрирующиеся вокруг эпизода № 38.
StackOverflow Вы можете преобразовать его в тип intptr_t
. Это тип int
, гарантированно достаточно большой, чтобы содержать указатель. Используйте #include
, чтобы определить его.
То, что вам может понадобиться, это
int x = reinterpret_cast<int>(arg);
Это позволяет вам заново интерпретировать void *
как int
.
Правильный способ - преобразовать его в другой указатель введите
. Преобразование void *
в int
- непереносимый способ, который может работать, а может и не работать! Если вам нужно сохранить возвращенный адрес, просто оставьте его как void *
.
Не передавайте int как void *
, передайте int *
вашему int
, поэтому вы можете преобразовать void *
в int *
и скопировать разыменованный указатель на свой int
.
int x = *static_cast<int*>(arg);
Приведение указателя к void * и обратно является допустимым использованием reinterpret_cast <>. Итак, вы можете сделать это:
pthread_create(&thread, NULL, myFcn, new int(5)); // implicit cast to void* from int*
Затем в myFcn:
void* myFcn(void* arg)
{
int* data = reinterpret_cast<int*>(arg);
int x = *data;
delete data;
Примечание: как указывает sbi, для создания потока потребуется изменить вызов OP.
На чем я пытаюсь выделить это преобразование из int в указатель и обратно могут вызвать проблемы при переходе с платформы на платформу. НО преобразование указателя в void * и обратно хорошо поддерживается (везде).
Таким образом, в результате может быть менее подвержено ошибкам динамическое создание указателя и его использование. Не забываем удалить указатель после использования, чтобы не протечь.
В общем случае нет правильного способа привести это к int
. Стандартная библиотека C99 предоставляет typedef intptr_t
и uintptr_t
, которые предполагается использовать всякий раз, когда возникает необходимость выполнить такое приведение. Если ваша стандартная библиотека (даже если это не C99) предоставляет эти типы - используйте их. Если нет, проверьте размер указателя на своей платформе, определите эти определения типов самостоятельно и используйте их.
Если вы вызовете свой поток функция создания, подобная этой
pthread_create(&thread, NULL, myFcn, reinterpret_cast<void*>(5));
, тогда void *
, прибывающая внутри myFcn
, имеет значение int
, которое вы в нее поместили. Итак, вы знаете, что можете вернуть его обратно, как это
int myData = reinterpret_cast<int>(arg);
, даже если компилятор не знает, что вы всегда передаете myFcn
в pthread_create
в сочетании с целым числом.
Править :
Как было указано Мартином, это предполагает, что sizeof (void *)> = sizeof (int)
.
Вместо:
int x = (int)arg;
используйте:
int x = (long)arg;
На большинстве платформ указатели и длинные значения имеют одинаковый размер, но целые числа и указатели часто имеют разные размеры на 64-битных платформах. Если вы преобразуете ( void *
) в ( long
), точность не будет потеряна, тогда путем присвоения ( long
) ( int
]), он правильно обрезает число, чтобы оно поместилось.
Что ж, он делает это, потому что вы конвертируете 64-битный указатель в 32-битное целое число, поэтому вы теряете информацию.
Вместо этого можно использовать 64-битное целое число, но я обычно использую функцию с правильным прототипом и привожу тип функции: например,
void thread_func(int arg){
...
}
, и я создаю поток следующим образом:
pthread_create(&tid, NULL, (void*(*)(void*))thread_func, (void*)arg);