C++ 指针总结

1 指针引用

引用不可以改变指向,对一个对象"至死不渝";但是指针可以改变指向,而指向其它对象。说明:虽然引用不可以改变指向,但是可以改变初始化对象的内容。例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容

Ep:错误用法

将指针p传入函数Malloc的参数p_val时,p_val = p 指向同一块内存。修改p_val 的值等同于修改p的值。

但是p_val = malloc 时,将p_val 指向了新申请的那块内存,p和p_val不再指向同一块内存。

 

修改为引用:p_val指向p的引用,修改p_val等同于修改p

2 取得成员函数指针

class A {

public:

       void Func(int a) {printf("func a = %d \n" ,a);}

};

int main()

{

       //::*是一个特殊的操作符,表示pFunc是一个指针,指向A的成员函数。

       //获取成员函数的地址不能通过类对象来获取,必须像上面的那样,

       //通过类名获取,而且要加上取地址操作符(&)。

       void (A::*pFunc)(int) = &A::Func;

       A a;

       (a.*pFunc)(10);//通过对象本身来调用

 

       A* pa = &a;

       (pa->*pFunc)(11);//通过对象指针来调用

       return 0;

}

第一种方式是通过对象本身来调用,第二种方式是通过对象指针来调用,两种方式的效果都是一样的。.*和->*都是特殊的操作符,不必纠结于它们奇怪的样子,只要知道它们只用于调用成员函数指针就行了。

 

3 使用类模板-成员函数指针

 

class A {

public:

       void Func(int a) {printf("func a = %d \n" ,a);}

};

 

class B

{

public:

       void Method(int b) {printf("func b = %d \n" ,b);}

};

 

template<typename T>//类模板

class DelegateHandler

{

public:

       DelegateHandler(T* pT, void (T::*pFunc)(int)) :

                     m_pT(pT), m_pFunc(pFunc)

       {

       }

       void Invoke(int value)

       {

              (m_pT->*m_pFunc)(value);

       }

private:

       T* m_pT;//对象指针

       void (T::*m_pFunc)(int);//类成员函数指针

};

 

 

int main()

{

       //::*是一个特殊的操作符,表示pFunc是一个指针,指向A的成员函数

       //获取成员函数的地址不能通过类对象来获取,必须像上面的那样,

       //通过类名获取,而且要加上取地址操作符(&)

       A a;

       DelegateHandler<A> ah(&a, &A::Func);

       ah.Invoke(3);

 

       B b;

       DelegateHandler<B> bh(&b, &B::Method);  //B::Method的声明与A::Func一致

       bh.Invoke(4);

 

       return 0;

}

 

4 模板偏特化-非成员函数指针

void NonmemberFunc(int f)

{

       printf("NonmemberFunc f = %d \n" ,f);

}

 

template<>

class DelegateHandler<void>

{

public:

       DelegateHandler(void (*pFunc)(int)): m_pFunc(pFunc) { }

 

       void Invoke(int value)

       {

              (*m_pFunc)(value);

       }

 

private:

       void (*m_pFunc)(int);

};

 

5 多态委托

将各种类型的DelegateHandler放到同一个容器中,并使用同样的方式来调用

class A {

public:

    void Func(int a) {printf("func a = %d \n" ,a);}

};

 

class B

{

public:

    void Method(int b) {printf("func b = %d \n" ,b);}

};

 

class IDelegateHandler

{

 

public:

    virtual ~IDelegateHandler() { }

    virtual void Invoke(int) = 0;

};

 

 

template<typename T>//类模板

class DelegateHandler : public IDelegateHandler//delegate 委托

{

public:

    DelegateHandler(T* pT, void (T::*pFunc)(int)) :

            m_pT(pT), m_pFunc(pFunc)

    {

    }

 

    void Invoke(int value)

    {

        (m_pT->*m_pFunc)(value);

    }

private:

    T* m_pT;//对象指针

    void (T::*m_pFunc)(int);//类成员函数指针

};

 

void NonmemberFunc(int h)

{

    printf("NonmemberFunc h = %d \n" ,h);

}

 

template<>

class DelegateHandler<void> : public IDelegateHandler

{

public:

    DelegateHandler(void (*pFunc)(int)): m_pFunc(pFunc) { }

 

    void Invoke(int value)

    {

        (*m_pFunc)(value);

    }

 

private:

    void (*m_pFunc)(int);

};

 

int main()

{

    A a;

    B b;

 

    DelegateHandler<A> ah(&a, &A::Func);

    DelegateHandler<B> bh(&b, &B::Method);

    DelegateHandler<void> vh(NonmemberFunc);

 

    //将各种类型的DelegateHandler放到同一个容器中,并使用同样的方式来调用了

    std::vector<IDelegateHandler*> handlers;

    handlers.push_back(&ah);

    handlers.push_back(&bh);

    handlers.push_back(&vh);

 

    for (auto it = handlers.begin(); it != handlers.end(); ++it) {

        (*it)->Invoke(7);

    }

    return 0;

}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值