拿这段代码:
struct mystruct
{
int var;
mystruct() : var(0) {}
};
int main()
{
mystruct ins;
int* p = &ins.var;
*p = 1;
}
那么什么是类成员指针使用的具体非常好的例子呢?
int X::*p = &X::data; /* p contains offset */
X object;
X *objptr = new X;
int i = object.*p;
int j = objptr->*p;
答案 0 :(得分:8)
看来你的问题是关于指针指向数据 -member类型的指针。在C ++中,还有指向成员指针函数类型的指针。这两者在某种抽象层面上有一些共同点,但在其他方面它们是不同的。
指向数据成员类型的指针适用于类的任何实例。普通指针始终指向该类的特定实例的成员。指向数据成员类型的指针是从类对象开头的“运行时偏移”概念的更高级实现。它是 relative 指针。以这种方式,它与普通指针完全不同,普通指针是绝对指针。
为了说明一个例子,假设你有一个包含三个相同类型成员的类x
,y
和z
struct Point { int x, y, z; };
Point point_array[N];
并且您需要在整个数组中将所有具有相同名称的成员设置为0
,而不更改任何其他成员。以下是使用指针指向数据成员类型
void zero_members(Point points[], int n, int Point::*m) {
for (int i = 0; i < n; ++i)
points[i].*m = 0;
}
现在,通过使用此功能,您可以
zero_members(point_array, N, &Point::x);
将所有x
设置为零。或者你可以做到
zero_members(point_array, N, &Point::y);
将所有y
设置为零。您可以使用单个函数完成所有这些操作,同样重要的是,成员选择由运行时参数执行(而不是编译 - 时间一)。
你不能用普通的指针做这样的事情。事实上,你不能以任何其他方式做到这一点。
答案 1 :(得分:3)
这样您就可以在多个实例上访问该成员。
答案 2 :(得分:1)
嗯,这类似于要求使用goto
的好例子... ;-)好吧,它就在那里,有时它可以很方便,但任何“好”使用{{1}的例子可能会有争议。对于成员指针也是如此,它们非常低级。
对于成员函数指针,一个常见的用法是在事件驱动的系统中。将成员函数指针与指向相关类的对象的指针一起打包,并且您有一些非常类似于C#委托的东西。然后,您可以传递这个小的仿函数包,以及其他人的代码,例如一个GUI框架,可以在不知道它的情况下回调你的对象。
Boost库为此提供了一些支持,例如: goto
和boost::function
,TR1和即将推出的C ++ 0x标准库(基本上是Boost功能的一个子集)也是如此。
关于“低级别”,成员指针遵循特殊规则,让您无意中绕过boost::bind
访问限制。
干杯&amp;第h。,
- Alf