[英]'No Match' Errors with a member callback function using std::tr1::function
[英]Virtual member functions and std::tr1::function: How does this work?
这是一段代码示例。 请注意, B
是A
的子类,并且都提供唯一的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基于引用的对象进行更改(在本例中为a
或b
?)从更加坚定的角度来看,此代码如何正确运行?
这与使用普通成员函数指针的方式相同。 以下产生相同的输出:
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.