C++指针之间的赋值与转换规则总结

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 *pA;          //自定义类型指针
const  A *pA_c;
pFun pf;    //函数指针
 
void * pVoid;
const  void * pVoid_c;
 
// 1.任何类型的指针变量均可直接赋值给const void *
pVoid_c = pInt;         //ok
pVoid_c = pInt_c;       //ok
pVoid_c = pChar;        //ok
pVoid_c = pChar_c;      //ok
pVoid_c = pDouble;      //ok
pVoid_c = pDouble_c;    //ok
pVoid_c = pA;           //ok
pVoid_c = pA_c;         //ok
pVoid_c = pf;           //ok
 
// 2.任何类型的非const指针变量均可直接赋值给void *
pVoid = pInt;           //ok
pVoid = pChar;          //ok
pVoid = pDouble;        //ok
pVoid = pA;             //ok
pVoid = pf;             //ok
 
// 3.const指针变量不可直接赋值给void *,除非通过强制类型转换
pVoid = pInt_c;            //error: cannot convert from 'const int *' to 'void *'
pVoid = pChar_c;           //error: cannot convert from 'const char *' to 'void *'
pVoid = pDouble_c;         //error: cannot convert from 'const double *' to 'void *'
pVoid = pA_c;              //error: cannot convert from 'const A *' to 'void *'
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 = (A*)pA_c;             //ok:由const指针变量转非const指针变量
pA = (A*)pDouble;          //ok
pA = (A*)pf;               //ok        
pf = (pFun)pDouble;        //ok
pf = (pFun)pA;             //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  // B继承自A
{};
 
class  C
{};
 
A* pA;
B* pB;
C* pC;
 
pA = pB;        //ok: 子类型指针变量可直接赋值给父类型指针变量
pB = pA;        //error: 父类型指针变量不可直接赋值给子类型指针变量,除非强制类型转换
                 //以下适用规则二:
pA = (A*)pC;    //ok
pB = (B*)pA;    //ok
pB = (B*)pC;    //ok
pC = (C*)pA;    //ok
pC = (C*)pB;    //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  * pVoid;
int  * pInt;
FunPtr fp;
AFunPointer afp;
 
pVoid = afp;          //error: cannot convert from 'AFunPointer' to 'void *'
pInt = ( int *)afp;     //error: 'type cast' : cannot convert from 'AFunPointer' to 'int *'
fp = (FunPtr)afp;     //error: 'type cast' : cannot convert from 'AFunPointer' to 'FunPtr'
 
afp = (AFunPointer)pInt;     //error: 'type cast' : cannot convert from 'int *' to 'AFunPointer'
afp = (AFunPointer)pVoid;    //error: 'type cast' : cannot convert from 'void *' to 'AFunPointer'
afp = (AFunPointer)fp;       //error: 'type cast' : cannot convert from 'FunPtr' to 'AFunPointer'

我们可以这样理解:类的成员函数指针被限定在具体的某个类的作用域中了,他不能和域外的指针之间转换。

 

2、除去类的成员函数指针,虽然任意类型指针变量之间均可以强制类型转换,也即可以将const指针强转为非const指针。

    但是应注意:如果将const指针强转为非const指针而用于原本const的对象,则产生未定义行为(C++语言未对此种情况进行规定)。如:

1
2
3
4
5
6
7
const  int  a = 50;   // 定义const变量及常量
const  int * p = &a;  // const指针变量p指向const变量a
int * q = ( int *)p;   // const指针强转为非const指针,则非const指针变量q指向const变量a
*q = 56;            // 行为未定义,以下输出为VS2008下的输出结果
cout << a << endl;      //输出: 50
cout << *p << endl;     //输出: 56,很显然,p已经不指向a了
cout << *q << endl;     //输出: 56,很显然,q已经不指向a了

 

3、关于一般函数指针的强制转换,以下当然也是OK的。

复制代码
class A;
typedef void (*pFun1)(int, int);
typedef int  (*pFun2)(A*, double);

pFun1 pf1;
pFun2 pf2;
pf2 = (pFun2)pf1;    // OK
复制代码

转载于:https://www.cnblogs.com/lanqiu5ge/p/9472249.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值