C++类基础9——类成员指针

类成员指针

成员指针是指可以指向类的非静态成员的指针。

一般情况下,指针指向一个对象,但是成员指针指示的是类的成员,而非类的对象。

类的静态成员不属于任何对象,因此无须特殊的指向静态成员的指针,指向静态成员的指针与普通指针没有什么区别。

成员指针的类型囊括了类的类型以及成员的类型。

当初始化一个这样的指针时,我们令其指向类的某个成员,但是不指定该成员所属的对象:直到使用成员指针时,才提供成员所属的对象。

为了解释成员指针的原理,我们定义下面这个类:

class Screen
{
public:

typedef std::string::size_type pos;

char get_cursor() const  
{
return contents[cursor];
}

char get() const;
char get (pos ht, pos wd) const;

private:
std::string contents;
pos cursor;
pos height, width;
};

数据成员指针

和其他指针一样,在声明成员指针时我们也使用*来表示当前声明的名字是一个指针。

与普通指针不同的是,成员指针还必须包含成员所属的类。

因此,我们必须在*之前添加classname::以表示当前定义的指针可以指向classname的成员。

例如:

// pdata可以指向一个常量(非常量)Screen对象的string成员
const string Screen:: *pdata;

上述语句将pdata 声明成“一个指向Screen类的const string成员的指针”。

常量对象的数据成员本身也是常量,因此将我们的指针声明成指向const string 成员的指针意味着pdata可以指向任何Screen对象的一个成员,而不管该Screen对象是否是常量。

作为交换条件,我们只能使用pdata读取它所指的成员,而不能向它写入内容。

当我们初始化一个成员指针(或者向它赋值)时,需指定它所指的成员。

例如,我们可以令pdata指向某个非特定Screen对象的contents成员:(前提是contents成员不是私有的)

pdata =&Screen::contents;

其中,我们将取地址运算符作用于Screen类的成员而非内存中的一个该类对象。

当然,在C++11 新标准中声明成员指针最简单的方法是使用auto或decltype:

auto pdata = &Screen::contents;

使用数据成员指针

读者必须清楚的一点是,当我们初始化一个成员指针或为成员指针赋值时,该指针并没有指向任何数据。

成员指针指定了成员而非该成员所属的对象,只有当解引用成员指针时我们才提供对象的信息。

与成员访问运算符 . 和->类似,也有两种成员指针访问运算符:.*和->*,这两个运算符使得我们可以解引用指针并获得该对象的成员:

Screen myScreen, *pScreen =&myScreen;
//.*解引用pdata以获得myScreen 对象的 contents成员
auto s = myScreen. *pdata;
//->*解引用pdata以获得pScreen 所指对象的 contents成员
s = pScreen->*pdata;

从概念上来说,这些运算符执行两步操作:它们首先解引用成员指针以得到所需的成员;然后像成员访问运算符一样,通过对象(.*)或指针(->*)获取成员。

像下面这样子使用数据成员指针

	const string Screen::* pdata = &Screen::contents;
	Screen a;
	auto b = a.*pdata;

返回数据成员指针的函数

常规的访问控制规则对成员指针同样有效。

例如,Screen的contents成员是私有的,因此之前对于pdata的使用必须位于Screen类的成员或友元内部,否则程序将发生错误。

因为数据成员一般情况下是私有的,所以我们通常不能直接获得数据成员的指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值