Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.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_Pointers - Fatal编程技术网

C++ 何时使用空指针?

C++ 何时使用空指针?,c++,c,pointers,C++,C,Pointers,我理解在malloc实现中使用void指针 void* malloc ( size_t size ); 有人能提出其他理由或提供一些在实践中有用的场景吗 谢谢如果你与C代码接口,需要通过C++对象,但是C库只会使用一个通用指针,那么当你检索指针时,你需要将它重新转换成适当的类型。 Void指针可能不应该经常使用,但是当你试图使用一个与任意指针一起工作的库函数时,它们会很有帮助,而且并不真正关心该内存代表什么数据。了解Void*和其他C主题的一个好方法是观看本书的前半部分iTunes-U上的“

我理解在malloc实现中使用void指针

void* malloc  ( size_t size );
有人能提出其他理由或提供一些在实践中有用的场景吗


谢谢

如果你与C代码接口,需要通过C++对象,但是C库只会使用一个通用指针,那么当你检索指针时,你需要将它重新转换成适当的类型。
Void指针可能不应该经常使用,但是当你试图使用一个与任意指针一起工作的库函数时,它们会很有帮助,而且并不真正关心该内存代表什么数据。

了解Void*和其他C主题的一个好方法是观看本书的前半部分iTunes-U上的“编程范例”。它真的很好地解释了void*(C泛型)和指针!它确实帮助我更好地学习C

如果希望能够在函数中接受不同类型的数据,最大的用途之一就是使用void*。 (这里有一个例子:)

下面是您可以使用它们的另一个示例:

  int i;
  char c;
  void *the_data;

  i = 6;
  c = 'a';

  the_data = &i;
  printf("the_data points to the integer value %d\n", *(int*) the_data);

  the_data = &c;
  printf("the_data now points to the character %c\n", *(char*) the_data);

如果您不想观看免费的斯坦福课程,我建议您在谷歌上搜索void pointer并阅读那里的所有资料。

当您编写需要在多个操作系统上运行并且需要相当不知道底层框架API的代码时,void pointer非常有用

例如,OS X、Windows和Linux都有Windows对象的基本概念,但它们都非常不同。因此,我有一些通用代码将它们作为void*传递,然后是特定于平台的实现,将void*转换为本机类型(HWND等)


但是,是的,正如其他人在本帖中所说,除非必要,否则肯定要避免这种情况。

void
指针应该在数据块的内容不重要的任何时候使用。例如,在复制数据时,会复制内存区域的内容,但数据的格式并不重要

对于在内存块上运行而不需要使用
void
指针理解内容的函数,指针向用户阐明了设计,以便用户知道函数不关心任何数据格式。 当函数实际上是内容无关的时,通常对函数进行编码,以获取
char*
来处理内存块。

查看。启动SQL查询并希望以某种方式处理结果(将结果存储到容器中)。调用sqlite3_exec()并将回调指针和void*指针传递给所需的任何对象(包括容器)。当sqlite3_exec()运行时,它会为每个检索到的行调用回调,并将void*指针传递到其中,以便回调可以强制转换指针并执行您想要的任何操作


重要的是sqlite3_exec()不关心回调的作用和传递的指针。void*正是针对此类指针的。一个好的场景是当您想要实现任何通用ADT时,如果您不知道它将保留和处理什么样的数据类型。例如,如下所示的链接列表:

typedef struct node_t node;
struct
{
    void* data;
    node* prev, next;
} node_t;

typedef struct list_t list;
typedef void* (func)(void*) cpy_func;
typedef void (func)(void*) del_func;
struct
{
   node* head, tail, curr;
   cpy_func copy;
   del_func delete;
} list_t;

initializeLinkedList(cpy_func cpy, del_func del);
//here you keep going defining an API
例如,在这里,您将传递到其他函数的初始化函数指针,这些函数将能够将您的数据类型复制到列表中,然后将其释放。因此,使用
void*
可以使列表更通用

<>我认为 Value>代码只保留了C++的兼容性,因为在C++中,你有更安全和复杂的方法来实现与模板、函子等相同的结果,而在编程C++时不需要使用Maloc。

关于C++,我没有任何具体的有用例子。

它在数字代码中是常用的,例如C根求解函数可能看起来是:

double find_root(double x0, double (*f)(double, void*), void* params)
{
/* stuff */
y = f(x, params);
/* other stuff */
}
params
f
转换为它知道的某种结构,但
find_root
不知道。

用void*实现的此类C“泛型”的另一个示例是标准qsort函数:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

您可以对任何类型的数组进行排序:int、long、double、char*或某些结构指针…

除了与C接口之外,我发现自己只在需要调试/跟踪某些代码并想知道某个指针的地址时使用void指针

SomeClass * myInstance;
// ...
std::clog << std::hex << static_cast< void* >(myInstance) << std::endl;
而且,在我看来,很好地记录了我正在尝试做的事情(知道指针地址,而不是关于实例的任何信息)


使编译器高兴

void*
实际上是一种C-ism,它允许C做一些它不可能做的事情

char*
不能移植用于任何事情,因为不同的平台可以生成不同类型的指针-a
char*
不一定与
void*
处理相同(甚至大小相同)

因此,当数据类型在C中未知(或者是多态的或动态的)时,
void*
允许您生成正确的底层指针类型—可以正确指向任何对象的指针类型


代码>虚空*/COD>一般不应该出现,除非在一个或另一个窗体中与遗留C代码接口。

使用空穴指针有很大的优势。 指针变量是存储另一个变量地址的变量。 例如:

int a;
int *x= &a;
现在,“x”存储整数变量的地址

void *pointer = &i;
void *pointer = &f;
但这一次失败了:

float f;
int *x = &f;
因为整型指针变量只能存储整型变量地址。 同样,它也适用于其他数据类型

当您使用void*指针时,它提供了一个边缘来存储任何类型变量的地址

void *pointer = &i;
void *pointer = &f;
在检索时,它必须被延迟

*((int*)pointer)
因此,请仔细使用void指针


<>这可能对你有帮助,

在C++中,我发现最重要的用例是空洞*指针,它给代码提供了一个选项,用来存储任意的“用户数据”,在他们已经使用的对象上。 假设你已经写了一节课
*((int*)pointer)
class Car
{
    public:

        // Existing methods of your Car class

        void setContentsOfTrunk(void* contentsOfTrunk);
        void* contentsOfTrunk() const;

    private:

        void* m_contentsOfTrunk;
}
template <class TrunkContentsType>
class Car
{
    public:

        // Existing methods of your Car class

        void setContentsOfTrunk(TrunkContentsType contentsOfTrunk);
        TrunkContentsType contentsOfTrunk() const;

    private:

        TrunkContentsType m_contentsOfTrunk;
}
class Car
{
    public:

        // Existing methods of your Car class
        // No methods having anything to do with trunk contents.

    private:

        // No data member representing trunk contents.
}

class CarWithTrunkContents
{
    public:

        // Existing methods of your Car class

        void setContentsOfTrunk(TrunkContentsType contentsOfTrunk);
        TrunkContentsType contentsOfTrunk() const;

    private:

        TrunkContentsType m_contentsOfTrunk;
}
class Car
{
    public:

        // Existing methods of your Car class

        void setUserData(void* userData);
        void* userData() const;

    private:

        void* m_userData;
}