这是一段代码示例。请注意,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;
}
的引用。
A
B
以下是我看到用GCC 4.2编译的输出:
std::tr1::function
我会考虑这种正确的行为,但鉴于在这两种情况下&A::print
都绑定到&A::print
,我无法解释它是如何正常工作的。有人可以赐教我吗?
编辑:感谢您的回答。我熟悉继承和多态类型。我感兴趣的是a
是什么意思?它是vtable的偏移量,并且vtable基于引用的对象(在这种情况下,b
或{{1}}进行更改?)从更加严格的角度来看,此代码的行为如何?正确?
答案 0 :(得分: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做了任何不同的事情,那将是令人惊讶的,因为他们可能会将这些指针存储在引擎盖下的成员函数中。哦,当然,如果没有指向the Fast Delegates article的链接,就不会提及这些指针。
答案 1 :(得分:2)
由于print()
被声明为virtual
,A
是一个多态类。通过绑定到print
函数指针,您将通过A
指针进行调用,其方式与:
A* ab = &b;
ab->print();
在上面的->print
调用中,您会发现多态行为。在您的代码中也是如此。如果你问我,这是一件好事。至少,大部分时间。 :)