Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么函数接受空指针?_C++_C_Pthreads_Parameter Passing_Void Pointers - Fatal编程技术网

C++ 为什么函数接受空指针?

C++ 为什么函数接受空指针?,c++,c,pthreads,parameter-passing,void-pointers,C++,C,Pthreads,Parameter Passing,Void Pointers,我试图理解pthread 但是,需要按如下方式创建线程方法: void *SomeMethod(void* x) { //Do Something } 为什么需要创建一个接受void指针的函数?我们不能将pthread与这样的函数一起使用吗 void SomeMethod() { } 因为pthread\u create函数接受类型为void*(*)(void*)的参数,这是一个接受void*并返回void*的函数,所以要使用pthread\u create创建线程,您需要使用它 p

我试图理解pthread

但是,需要按如下方式创建线程方法:

void *SomeMethod(void* x)
{
    //Do Something
}
为什么需要创建一个接受
void
指针的函数?我们不能将pthread与这样的函数一起使用吗

void SomeMethod()
{
}

因为
pthread\u create
函数接受类型为
void*(*)(void*)
的参数,这是一个接受
void*
并返回
void*
的函数,所以要使用
pthread\u create
创建线程,您需要使用它

pthread\u create
API使用该函数将数据传递给新线程并再次获取数据。如果您不想传入任何内容,您仍然必须满足该接口,但只需将其传入NULL即可

仅仅因为您现在不想向新线程传递任何参数,并不意味着API应该设计为只支持您当前的用例。让API以函数形式编写,函数采用
void*
(可以选择传递NULL),比让API以函数形式编写,函数不采用参数,并要求用户提出自己的解决方案,以便将数据传递给新线程要好得多

<>在C++中,可以使用任何类型的函数来处理新线程,并将其传递给您需要的任何参数:

std::thread t(&SomeMethod);

因为
pthread\u create
函数接受类型为
void*(*)(void*)
的参数,这是一个接受
void*
并返回
void*
的函数,所以要使用
pthread\u create
创建线程,您需要使用它

pthread\u create
API使用该函数将数据传递给新线程并再次获取数据。如果您不想传入任何内容,您仍然必须满足该接口,但只需将其传入NULL即可

仅仅因为您现在不想向新线程传递任何参数,并不意味着API应该设计为只支持您当前的用例。让API以函数形式编写,函数采用
void*
(可以选择传递NULL),比让API以函数形式编写,函数不采用参数,并要求用户提出自己的解决方案,以便将数据传递给新线程要好得多

<>在C++中,可以使用任何类型的函数来处理新线程,并将其传递给您需要的任何参数:

std::thread t(&SomeMethod);

因为他们只想编写一个创建线程的函数——获取和返回数据

否则,他们必须写出至少四种可能性

您可以忽略输入参数和返回值


简单一点

因为他们只想编写一个创建线程的函数——获取和返回数据

否则,他们必须写出至少四种可能性

您可以忽略输入参数和返回值

简单一点

根据
pthread_create()
的说明,我们可以看到,函数的签名是

 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
               void *(*start_routine) (void *), void *arg);
其中第三个参数的类型为

void *(*start_routine) (void *)
这意味着,它需要一个指向返回类型为
void*
并接受
void*
参数的函数的指针。因此,我们需要相应地定义线程函数

也就是说,关于参数传递的
void
指针的使用,引用
C11
,第§6.3.2.3章

指向
void
的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。指向任何对象类型的指针可以转换为指向
void
的指针,然后再返回;结果应与原始指针进行比较

如我们所见,
void
指针用于将任何类型的数据传递给线程函数,前提是它被转换回函数内部的实际类型

此外,FWIW,不要试图偏离函数指针所需的签名,因为标准明确要求

[…]如果使用转换的指针调用类型与引用类型不兼容的函数,则行为未定义。如果您不想(需要)传递任何有效的参数值,您可以始终传递
NULL

根据
pthread\u create()
,我们可以看到,函数的签名是

 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
               void *(*start_routine) (void *), void *arg);
其中第三个参数的类型为

void *(*start_routine) (void *)
这意味着,它需要一个指向返回类型为
void*
并接受
void*
参数的函数的指针。因此,我们需要相应地定义线程函数

也就是说,关于参数传递的
void
指针的使用,引用
C11
,第§6.3.2.3章

指向
void
的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。指向任何对象类型的指针可以转换为指向
void
的指针,然后再返回;结果应与原始指针进行比较

如我们所见,
void
指针用于将任何类型的数据传递给线程函数,前提是它被转换回函数内部的实际类型

此外,FWIW,不要试图偏离函数指针所需的签名,因为标准明确要求

[…]如果使用转换的指针调用类型与引用类型不兼容的函数,则行为未定义。如果您不想(需要)传递任何有效的参数值,您可以始终传递
NULL


因为很多时候,我们想要给线程一些工作(或者使用,或者关闭,或者其他)。一个非常典型的例子是传入一个类的实例,这样就可以调用类成员函数

但它可以是各种各样的东西——结构,或者指向一些简单数据的指针

当然,无论如何,使用
std::thread
都会隐藏大部分这样的东西,您不必担心。我强烈建议使用