类成员指针的作用是什么?

7

我已经了解了关于类成员指针的知识,但是我从未见过它们在任何实际应用中被使用。能否有人解释一下这些指针的用例?是否真的有必要使用这样的指针?

例如:

class abc
{
public:
    int a;
    abc(int val) { a = val; }
};

 int main()
{
   int abc::*data;
   abc obj(5);

   data = &abc::a;

   cout << "Value of a is " << obj.*data << endl;

   return 0;
}

在上面的例子中,为什么要以这种方式访问“a”的值?使用类成员指针的优点是什么?
4个回答

9
指向成员或成员函数的指针最大的优点是,你
  • 不需要立即绑定到特定实例
  • 不需要对成员名称施加任何限制,只需类型匹配即可。
这可以用于回调或抽象算法:
std::map<int,int> m;
m.insert(std::make_pair(1,2));
m.insert(std::make_pair(3,4));
m.insert(std::make_pair(5,6));
std::ptrdiff_t s = 
    std::count_if(m.begin(), m.end(),
                  boost::bind(&std::map<int,int>::value_type::first, _1) > 2);
std::cout << s << std::endl; // 2

请注意,Boost.Bind、Boost.Function及其TR1等效项已经很好地封装了它们。在某种程度上,当前标准还包括像<functional>中的std::mem_fun之类的工具。

是的,但它们封装了使用方式 - 我现在已经很长时间没有需要声明指向成员的指针了。 - Georg Fritzsche
为了演示的清晰性,我可能会使用map::operator[]insertmake_pair的组合过于冗长 :p 很好的答案,谢谢 :) - Matthieu M.

2

如果您使用过MFC,您将会看到指向成员函数的概念被广泛使用(在内部)

DECLARE_MESSAGE_MAP、BEGIN_MESSAGE_MAP和END_MESSAGE_MAP 请参见消息映射


0
我认为这个问题是:“指向成员数据的指针相对于简单数据指针有什么优势?” 我能够想到的唯一答案就是增加了一定程度的显式含义:我们正在指向这个类中的数据。
现在我可以看到某些价值,实际上是一些额外的意图说明文档。我看过的一个可能非常强大的例子是当我们的“类”实际上是一个传统的C结构体时。现在我们没有该结构体的本地方法,因此具有明确关联该结构体的某些指针可能会使我们的代码更清晰。

1
如果您同时指定类实例和变量,则会得到一个普通指针(地址完全确定)。只有在指定变量而不指定类实例时,您才会得到一个成员指针,它基本上只是从实例开头到存储该变量的位置的偏移量。这已经足够的信息去访问类的任何实例中的变量。 - Ben Voigt

0

成员指针就像所有C++特性一样,只是纯C中已经存在的东西的语法糖。

成员变量指针非常简单。一个使用案例是,如果您想编写一个(模板)函数,可以按任何字段对结构数组进行排序。通过传递成员指针,您可以检索结构的任何实例的某个指定字段,而无需硬编码该字段。当然,也可以使用接受结构指针并返回字段值的函数对象。

成员函数指针有点复杂。乍一看,它们就像知道如何传递隐藏的“this”指针的普通函数指针一样。但虚函数使得一个简单的想法变得相当复杂。

而虚基类使得所有成员指针都变得非常复杂。这不是您想使用简单的C构造自己编写的东西。但是复杂情况很少见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接