3

Here is a sample piece of code. Note that B is a subclass of A and both provide a unique print routine. Also notice in main that both bind calls are to &A::print, though in the latter case a reference to B is passed.

#include <iostream>
#include <tr1/functional>

struct A
{
    virtual void print()
    {
        std::cerr << "A" << std::endl;
    }
};

struct B : public A
{
    virtual void print()
    {
        std::cerr << "B" << std::endl;
    }
};

int main (int argc, char * const argv[])
{
    typedef std::tr1::function<void ()> proc_t;

    A a;
    B b;

    proc_t a_print = std::tr1::bind(&A::print, std::tr1::ref(a));
    proc_t b_print = std::tr1::bind(&A::print, std::tr1::ref(b));

    a_print();
    b_print();

    return 0;
}

Here is the output I see compiling with GCC 4.2:

A
B

I would consider this correct behavior, but I am at a loss to explain how it is working properly given that the std::tr1::functions were bound to &A::print in both cases. Can someone please enlighten me?

EDIT: Thanks for the answers. I am familiar with inheritance and polymorphic types. What I am interested in is what does &A::print mean? Is it an offset into a vtable, and that vtable changes based on the referred object (in this case, a or b?) From a more nuts-and-bolts perspective, how does this code behave correctly?

4

2 回答 2

5

这与使用普通成员函数指针的方式相同。以下产生相同的输出:

int main ()
{
    A a;
    B b;
    typedef void (A::*fp)();
    fp p = &A::print;
    (a.*p)(); // prints A
    (b.*p)(); // prints B
}

如果 boost/tr1/std::function 做了任何不同的事情,那将是令人惊讶的,因为它们可能将这些指向成员函数的指针存储在引擎盖下。哦,当然,如果没有指向Fast Delegates 文章的链接,这些指针的提及是不完整的。

于 2010-09-09T17:41:42.620 回答
2

因为print()被声明virtualA是一个多态类。通过绑定到print函数指针,您将通过A指针进行调用,与以下方式大致相同:

A* ab = &b;
ab->print();

在上面的->print调用中,您会期望多态行为。在您的代码中也是如此。如果你问我,这是一件好事。至少,大多数时候。:)

于 2010-09-09T17:20:57.513 回答