虚拟成员函数和 std::tr1::function:这是如何工作的?
这是一段示例代码。请注意,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
?)而变化? ,这段代码如何正确运行?
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::function
s 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它的工作方式与普通成员函数指针的工作方式相同。以下产生相同的输出:
如果 boost/tr1/std::function 做了任何不同的事情,那将会令人惊讶,因为它们可能将这些指向成员函数的指针存储在引擎盖下。哦,当然,如果没有 Fast Delegates 文章<的链接,这些指针的提及就不完整。 /a>.
This works in the same manner as it would have worked with plain member function pointers. The following produces the same output:
It would have been surprising if boost/tr1/std::function did anything different since they presumably store these pointers to member functions under the hood. Oh, and of course no mention of these pointers is complete without a link to the Fast Delegates article.
因为
print()
被声明为virtual
,所以A
是一个多态类。通过绑定到print
函数指针,您将通过A
指针进行调用,与以下方式非常相似:在
->print
中> 在上面调用,您会期望多态行为。您的代码中也是如此。如果你问我的话,这是一件好事。至少,大多数时候。 :)Because
print()
is declaredvirtual
,A
is a polymorphic class. By binding to theprint
function pointer, you will be calling through anA
pointer, much in the same way as:In the
->print
call above, you would expect polymorphic behavior. Same it true in your code as well. And this is a Good Thing, if you ask me. At least, most of the time. :)