繁体   English   中英

虚拟成员函数和std :: tr1 :: function:这是如何工作的?

[英]Virtual member functions and std::tr1::function: How does this work?

这是一段代码示例。 请注意, BA的子类,并且都提供唯一的print例程。 在还要注意main两者bind呼叫是到&A::print ,虽然在后一种情况下,以基准B传递。

#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;
}

这是我看到用GCC 4.2编译的输出:

A
B

我会考虑这种正确的行为,但我无法解释它是如何正常工作的,因为std::tr1::function在两种情况下都绑定到&A::print 有人可以赐教吗?

编辑:谢谢你的答案。 我熟悉继承和多态类型。 我感兴趣的是&A::print 什么意思 它是否为vtable的偏移量,并且vtable基于引用的对象进行更改(在本例中为ab ?)从更加坚定的角度来看,此代码如何正确运行?

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

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文章的链接, 不会提及这些指针。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM