有时,我们希望获得类的特定成员的指针,然后从一个对象或别的对象获得该成员,这时可以通过使用称为成员指针的特殊种类的指针。
成员指针包含类的类型以及成员的类型,成员指针只应用于类的非static成员。因为static类成员不是任何对象的组成部分,因此不需要特殊语法来指向static成员,static成员指针是普通指针。
先看下面的类:
class ASCEScreen
{
public:
typedef std::string::size_type index;
wchar_t get() const;
wchar_t get(index ht, index wd) const;
private:
std::string contents;
index cursor;
index height, width;
};
1)定义数据成员的指针
可以指向contents的指针的完全类型是:“指向std::string类型的ASCEScreen类成员的指针”,而可以指向ASCEScreen类的std::string成员的指针定义就是:
std::string ASCEScreen::*ps_ASCEScreen;
可以用contents的地址初始化ps_ASCEScreen:
std::string ASCEScreen::*ps_ASCEScreen = &ASCEScreen::contents;
2)定义成员函数的指针
成员函数的指针必须在三个方面与它所指函数的类型相匹配:
1---函数形参的类型和数目,包括成员是否为const;
2---返回类型;
3---所属类的类型。
通过指定函数返回类型、形参表和类来定义成员函数的指针,例如可引用不接受形参的get版本的ASCEScreen成员函数的指针具有如下类型:
wchar_t (ASCEScreen::*pmf) () const = &ASCEScreen::get;
带两个形参的get函数版本的指针定义如下:
wchar_t (ASCEScreen::*pmf) (ASCEScreen::index, ASCEScreen::index) const;
pmf = &ASCEScreen::get;
3)为成员指针使用类型别名
类型别名可以使成员指针更容易阅读,下面的类型别名将Action定义成带两个形参的get函数版本的类型的另一个名字:
typedef wchar_t (ASCEScreen::*Action) (ASCEScreen::index, ASCEScreen::index) const;
Action现在就是类型“ASCEScreen类的接受两个index类型形参并返回wchar_t的成员函数的指针”的名字了。使用类型别名,可以将get指针定义简化为:
Action ASCEGet = &ASCEScreen::get;
可以使用成员指针函数类型来声明函数形参和函数返回类型:
ASCEScreen& action(ASCEScreen&, Action = &ASCEScreen::get);
这个函数声明为接受两个形参:ASCEScreen对象的引用,以及ASCEScreen类接受两个index类型形参并返回wchar_t的成员函数的指针。
这样就可以通过传递ASCEScreen类中适当成员函数的指针或地址调用action函数:
ASCEScreen asceScreen;
//等价的调用
action(asceScreen);
action(asceScreen, get);
action(asceScreen, &ASCEScreen::get); //显式传地址
类似于成员访问操作符.和->,.*和->*是两个新的操作符:
成员指针解引用操作符.*从对象或引用获取成员;
成员指针箭头操作符->*通过对象的指针获取成员。
4)使用成员函数的指针
可以这样调用不带形参的get函数版本:
wchar_t (ASCEScreen::*pmf) () const = &ASCEScreen::get;
ASCEScreen asceScreen;
wchar_t c1 = asceScreen.get();
wchar_t //等同与调用get()
ASCEScreen *pasceScreen = &asceScreen;
c1 = pasceScreen->get();
c2 = (pasceScreen->*pmf) (); //等同于调用get()
5)使用数据成员的指针
相同的成员指针操作符用于访问数据成员:
ASCEScreen::index ASCEScreen::*pindex = &ASCEScreen::width;
ASCEScreen asceScreen;
ASCEScreen::index ind1 = asceScreen.width;
ASCEScreen::index ind2 = asceScreen.*pindex; //同上
ASCEScreen *pasceScreen = &asceScreen;
ind1 = pasceScreen->width;
ind2 = pasceScreen->*pindex; //同上
6)成员指针函数表
函数指针和成员函数指针的一个公共用途是将它们存放在函数表中。函数表是函数指针的集合,在运行时从中选择给定的调用。
对具有几个相同类型成员的类来说,可以使用这样的表来从这些成艳的集合中选一个运行:
class ASCEScreen
{
public:
...
ASCEScreen& home();
ASCEScreen& forward();
ASCEScreen& back();
ASCEScreen& up();
ASCEScreen& down();
public:
typedef ASCEScreen& (ASCEScreen::*Action) ();
static //类成员函数指针表
enum Directions {HOME, FORWARD, BACK, UP, DOWN};
ASCEScreen& move(Directions);
};
//move函数接受枚举成员并调用相应的函数
ASCEScreen& ASCEScreen::move(Directions cm)
{
(this->*Menu[cm]) (); //调用函数
return *this;
}
//定义和初始化成员函数指针表Menu[]
ASCEScreen::Action ASCEScreen::Menu[] = {&ASCEScreen::home, &ASCEScreen::forward,
&ASCEScreen::back, &ASCEScreen::up, &ASCEScreen::down};
使用如下:
ASCEScreen asceScreen;
asceScreen.move(ASCEScreen::HOME); //调用asceScreen.home()函数
asceScreen.move(ASCEScreen::DOWN);//调用asceScreen.down()函数
《认清C++语言》---类成员的指针
原创
©著作权归作者所有:来自51CTO博客作者wx5dce75f541ce3的原创作品,请联系作者获取转载授权,否则将追究法律责任

提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
C语言指针的基本认识
C语言指针的基本认识
指针变量 指针类型 指针数组 -
C++:33---类成员指针
成员指针概述:当初始化一个这样的指针时,我们令其指向类的某个成员
成员函数 成员函数指针 运算符 -
认清C++语言之《制造抽象基类》
1) 抽象基类通常用于表示目标问题领域的抽象概念,创建这种类型的对象时没有任何意义的。我们通过至少声明一个纯虚函数
c++ 制造 语言 class 编译器 -
《认清C++语言》---堆对象
强制在堆中建立对象:有时候,我们要求某种类型的对象能够自我销毁,也就是能够“delelte this”,因此,我们需要将此类型的对象好将析构函数置为pr
语言 c++ delete class iterator -
C++成员变量指针和成员函数指针
深度探索C++对象模型这本书还有提到C++类的成员变量指针和成员函数指针,虽然在实际开发中用的不多,但是还是
c++ #include 偏移量 静态成员