类型转换运算符,类成员指针

一、类型转换运算符

转化成其他类类型

// 格式
operate type() const
{
    // 通过类返回指定的type类型的值
}
// 类型转换运算符必须要写成类的成员函数
// 例子
class Element{
explicit  operate int() const;  // explicit 禁止隐式类型转换
}
Element ele;
int k = ele + 5;    //  隐式调用
int k2 = ele.operate int() + 5;  //  显式调用
int k3 = static_cast<int>(ele) + 5;  // 当隐式类型转换被禁止的时,只能用强制类型转换

类型转换运算符转换成函数指针

class Element
    {
    public:
        // 函数指针类型
        // 用下面的两种方法都可以定义一个函数指针
        // typedef void(*funname)(int);  
        using funname = void(*)(int);
    public:
        static void GetElemnetId(int val)
        {
        }       
        // 函数类型转换符,能将本类转换成一个函数指针类型
        // 这样写了之后,Element(1),可以将类看成是一个函数名
        // 会调用funname()中返回的函数
        operator funname()  // const 不是必须的
        {
            // 因为这里已经制定了返回值类型为函数指针类型,所以需要返回一个函数名
            return GetElemnetId;
        }
    };

    Element ele;
    ele(1);    // 隐式调用,将类的对象直接当成了一个函数
    ele.operator Element::funname()(12);  // 显示的调用

二、类型转换的二义性问题

当一个类中有多个类型转换函数时,隐式调用会出现二义性问题,这时在调用类型转换运算符时候,一定要显式调用。

小结:

对于二义性问题,最简单的解决方式是全部显式地指定所调用的函数和转换的类型。

三、类的成员函数指针

class Element
{
public:
    void ptFun(int val) {};     // 普通成员函数
    virtual void virtualFun(int val) {};  // 虚成员函数
    static void staticFun(int val) {};    // 静态成员函数
};

int main()
{
    // 普通成员函数指针
    void (Element::*funname)(int);   // 一个类成员函数指针变量的定义
    funname = &Element::ptFun;       // 类成员函数指针变量funname被赋值
    // 成员函数是属于类的,不属于对象,只要有类在就有成员函数的地址
    // 但是如果要使用这个成员函数指针,就必须要把它绑定到一个类对象
    // 调用方式
    Element ele, *pEle;
    (ele.*funname)(2);    // 前面一定要加括号,因为后面的圆括号优先级更高
    (pEle->*funname)(2);  // 对象指针的调用
    
    // 虚成员函数指针,与普通函数写法相同
    void (Element::*virtualFunname)(int) = &Element::virtualFun;
    
    // 静态成员函数指针,定义和调用的时候,都不需要写类名
    void (*staticFunname)(int) = &Element::staticFun;
    staticFunname(10);   //直接调用,不需要通过类对象来调用
    cout << 1 << endl;
    system("pause");
    return 0;
}

四、类的成员变量指针

class Element
{
public:
    int m_val;     // 普通成员变量,属于对象
    static int s_val;   // 静态成员变量,属于类,不属于对象
};

int Element::s_val = 10;  // 静态成员变量的定义,类中只是在声明

int main()
{
    // 普通成员变量指针,只存了偏移量,需要绑定到对象上去用,才能得到真正的地址
    int Element::*pInt = &Element::m_val;   // 定义普通成员变量的指针
    // 不是指向内存中的某个地址,而是该成员变量,和这个类对象指针的偏移量
    // 就是成员变量与这个类对象的首地址之间的偏移量
    // 例如:如果偏移量是4个字节,那么pInt的值为 0x00000004
    Element ele;
    ele.*pInt = 10;   // 等价于ele.m_val = 10,用成员变量指针来给成员变量赋值

     // 静态成员变量指针,里面存的是真正的地址
    int * pStatic = &Element::s_val;   //定义一个静态成员变量指针
    *pStatic = 1;   // 等价于s_val = 1;  
   
    return 0;
}

 

posted @ 2020-06-16 20:28  min_zhi  阅读(237)  评论(0编辑  收藏  举报