fbr*_*eto 3 c++ inheritance tr1
这是一段代码示例.注意,它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;
}
Run Code Online (Sandbox Code Playgroud)
这是我看到用GCC 4.2编译的输出:
A
B
Run Code Online (Sandbox Code Playgroud)
我会考虑这种正确的行为,但我无法解释它是如何正常工作的,因为在两种情况下std::tr1::function
s都必然&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
}
Run Code Online (Sandbox Code Playgroud)
如果boost/tr1/std :: function做了任何不同的事情,那将是令人惊讶的,因为他们可能会将这些指针存储在引擎盖下的成员函数中.哦,当然,如果没有Fast Delegates文章的链接,就不会提及这些指针.