如果我可以在类中使用指向变量的普通指针,那么类成员指针的重点是什么?

时间:2010-10-10 01:24:20

标签: c++ class pointers member

拿这段代码:

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;

3 个答案:

答案 0 :(得分:8)

看来你的问题是关于指针指向数据 -member类型的指针。在C ++中,还有指向成员指针函数类型的指针。这两者在某种抽象层面上有一些共同点,但在其他方面它们是不同的。

指向数据成员类型的指针适用于类的任何实例。普通指针始终指向该类的特定实例的成员。指向数据成员类型的指针是从类对象开头的“运行时偏移”概念的更高级实现。它是 relative 指针。以这种方式,它与普通指针完全不同,普通指针是绝对指针。

为了说明一个例子,假设你有一个包含三个相同类型成员的类xyz

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库为此提供了一些支持,例如: gotoboost::function,TR1和即将推出的C ++ 0x标准库(基本上是Boost功能的一个子集)也是如此。

但是,我无法想象数据成员指针的任何常见用法。

关于“低级别”,成员指针遵循特殊规则,让您无意中绕过boost::bind访问限制。

干杯&amp;第h。,

- Alf