void pointer

85 篇文章 0 订阅

6.13 — Void pointers

The void pointer, also known as the generic pointer, is a special type of pointer that can be pointed at objects of any data type! A void pointer is declared like a normal pointer, using the void keyword as the pointer’s type:

1
void *pVoid; // pVoid is a void pointer

A void pointer can point to objects of any data type:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int nValue;
float fValue;
 
struct Something
{
     int nValue;
     float fValue;
};
 
Something sValue;
 
void *pVoid;
pVoid = &nValue; // valid
pVoid = &fValue; // valid
pVoid = &sValue; // valid

However, because the void pointer does not know what type of object it is pointing to, it can not be dereferenced! Rather, the void pointer must first be explicitly cast to another pointer type before it is dereferenced.

1
2
3
4
5
6
7
8
int nValue = 5;
void *pVoid = &nValue;
 
// can not dereference pVoid because it is a void pointer
 
int *pInt = static_cast < int *>(pVoid); // cast from void* to int*
 
cout << *pInt << endl; // can dereference pInt

Similarly, it is not possible to do pointer arithmetic on a void pointer. Note that since void pointers can’t be dereferenced, there is no such thing as a void reference.

The next obvious questions is: If a void pointer doesn’t know what it’s pointing to, how do we know what to cast it to? Ultimately, that is up to you to keep track of.

Here’s an example of a void pointer in use:

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
#include <iostream>
 
enum Type
{
     INT ,
     FLOAT ,
     STRING,
};
 
void Print( void *pValue, Type eType)
{
     using namespace std;
     switch (eType)
     {
         case INT :
             cout << * static_cast < int *>(pValue) << endl;
             break ;
         case FLOAT :
             cout << * static_cast < float *>(pValue) << endl;
             break ;
         case STRING:
             cout << static_cast < char *>(pValue) << endl;
             break ;
     }
}
 
int main()
{
     int nValue = 5;
     float fValue = 7.5;
     char *szValue = "Mollie" ;
 
     Print(&nValue, INT );
     Print(&fValue, FLOAT );
     Print(szValue, STRING);
     return 0;
}

This program prints:

5
7.5
Mollie

In general, it is a good idea to avoid using void pointers unless absolutely necessary, as they effectively allow you to avoid type checking. This allows you to inadvertently do things that make no sense, and the compiler won’t complain about it. For example, the following would be valid:

1
Print(&nValue, STRING);

But who knows what the result would actually be!

Although the above function seems like a neat way to make a single function handle multiple data types, C++ actually offers a much better way to do the same thing (via function overloading) that retains type checking to help prevent misuse. Many other places where void pointers would once be used to handle multiple data types are now better done using templates, which also offer strong type checking.

However, very occasionally, you may still find a reasonable use for the void pointer. Just make sure there isn’t a better (safer) way to do the same thing using other language mechanisms first!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值