为什么可以按类类型获取成员函数的地址

时间:2014-07-16 07:56:02

标签: c++ bind member-function-pointers pointer-to-member

我遇到了这段代码:

 auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);

在前面的代码中,我们可以在没有实例的情况下将地址运算符应用于成员函数 对象已创建,怎么可能?

3 个答案:

答案 0 :(得分:5)

C ++的类型系统包含一些鲜为人知的类型,它们是成员指针。给定任何类类型C以及任何对象或函数类型T,都有一个指向成员的类型T C::*。可以通过将address-of运算符应用于类成员的限定名称来获取这些类型的值。例如:

 struct Foo;

 int Foo::* pi;                  // C = Foo, T = int
 void (Foo::* pf)(bool, int);    // C = Foo, T = void(bool, int)

 struct Foo {
     int a;
     int b;
     void f(bool, int);
     void g(bool, int);
 };

 pi = &Foo::a;
 pf = &Foo::f;

成员指针本身只抽象地选择一个类成员,与任何类实例无关。要实际使用指针,您需要一个类实例,以及member-dereference运算符.*

Foo x;

int n = x.*pi;     // gets x.a
(x.*pf)(true, n);  // calls x.f(true, n)

pf = &Foo::g;
(x.*pf)(true, n);  // calls x.g(true, n)

(通过指向成员pf的调用表达式中的括号是必要的,否则表达式a.*b(c)表示a.*(b(c))。这有时会让新用户感到困惑。)

不要将指向成员的指针与指向实际对象的指针混淆对象!

int * p = &(x.*pi);   // p = &x.a

此处p指向实际的int子对象x.a并且是普通对象指针,而pi是指向成员的指针,它抽象地选择{{1} 1}} Foo::a对象的成员。

答案 1 :(得分:0)

使用Foo成员函数的地址为您提供指向成员函数的指针。此类型完全独立于任何Foo对象。如果您要实际调用该函数,则需要提供Foo对象。在这种情况下,this的{​​{1}}参数与Foo::print_sum绑定到&foo

答案 2 :(得分:0)

当然,您需要一个名为Foo的{​​{1}}类型的实例,因为成员函数foo绑定到Foo::print_sum