zoukankan      html  css  js  c++  java
  • 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
    复制代码
  • 相关阅读:
    Knockout应用开发指南 第十章:更多信息(完结篇)
    Knockout应用开发指南 第九章:高级应用举例
    汤姆大叔博客索引
    HTML5学习笔记简明版(1):HTML5介绍与语法
    HTML5学习笔记简明版 目录索引
    大叔手记(1):使用Visual Studio的查找与替换替代默认的系统搜索
    微软ASP.NET站点部署指南(9):部署数据库更新
    微软ASP.NET站点部署指南(11):部署SQL Server数据库更新
    彻底搞定C指针
    linux svn 使用
  • 原文地址:https://www.cnblogs.com/lanqiu5ge/p/9472249.html
Copyright © 2011-2022 走看看