C++指针之间的赋值与转换规则总结
Note:以下结论不适用于类的成员函数指针,关于类的成员函数指针会单独讨论。
一、任何类型的指针变量均可直接赋值给const void *
任何类型的非const指针变量均可直接赋值给void *
const指针变量不可直接赋值给void *,除非通过强制类型转换
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
|
class A
{
};
typedef int (*pFun)(string); //函数指针
int *pInt;
const int *pInt_c;
char *pChar;
const char *pChar_c;
double *pDouble;
const double *pDouble_c;
A //自定义类型指针
const A
pFun //函数指针
void *
const void *
//
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
pVoid_c //ok
//
pVoid //ok
pVoid //ok
pVoid //ok
pVoid //ok
pVoid //ok
//
pVoid //error:
pVoid //error:
pVoid //error:
pVoid //error:
pVoid void *)pInt_c; //ok
pVoid void *)pChar_c; //ok
pVoid void *)pDouble_c; //ok
pVoid void *)pA_c; //ok
|
二、任意类型指针变量之间均可以强制类型转换,包括const与非const指针变量之间的强制类型转换。
1
2
3
4
5
6
7
8
9
|
pInt int *)pDouble; //ok
pInt int *)pf; //ok
pInt int *)pInt_c; //ok:由const指针变量转非const指针变量
pInt int *)pA_c; //ok:由const指针变量转非const指针变量
pA //ok:由const指针变量转非const指针变量
pA //ok
pA //ok
pf //ok
pf //ok
|
三、有继承关系的自定义类型之间:子类型指针变量可直接赋值给父类型指针变量
父类型指针变量不可直接赋值给子类型指针变量,除非通过强制类型转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class A
{};
class B public A //
{};
class C
{};
A*
B*
C*
pA //ok:
pB //error:
//以下适用规则二:
pA //ok
pB //ok
pB //ok
pC //ok
pC //ok
|
补充:
1、对于类的成员函数指针,以上原则不适用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class A
{};
typedef void (A::*AFunPointer)( void );
typedef void (*FunPtr)( void );
void *
int *
FunPtr
AFunPointer
pVoid //error:
pInt int *)afp; //error:
fp //error:
afp //error:
afp //error:
afp //error:
|
我们可以这样理解:类的成员函数指针被限定在具体的某个类的作用域中了,他不能和域外的指针之间转换。
2、除去类的成员函数指针,虽然任意类型指针变量之间均可以强制类型转换,也即可以将const指针强转为非const指针。
但是应注意:如果将const指针强转为非const指针而用于原本const的对象,则产生未定义行为(C++语言未对此种情况进行规定)。如:
1
2
3
4
5
6
7
|
const int a //
const int * //
int * int *)p; //
*q //
cout //输出:
cout //输出:
cout //输出:
|
3、关于一般函数指针的强制转换,以下当然也是OK的。
class A;
typedef void (*pFun1)(int, int);
typedef int (*pFun2)(A*, double); pFun1 pf1;
pFun2 pf2;
pf2 = (pFun2)pf1; // OK