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;
}