C++ 虚拟成员函数和std::tr1::function:这是如何工作的?
下面是一段示例代码。请注意,C++ 虚拟成员函数和std::tr1::function:这是如何工作的?,c++,inheritance,tr1,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;
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;
}
我会考虑这个正确的行为,但是如果<>代码STD::Tr1::函数< /代码> s被绑定到<代码>:A::打印< /代码>这两种情况下,我都无法解释它是如何工作的。有人能告诉我吗
编辑:谢谢您的回答。我熟悉继承和多态类型。我感兴趣的是&A::print
是什么意思?它是vtable的一个偏移量,并且vtable根据引用的对象(在本例中为a
或b
?)而变化。从更具体的角度来看,该代码如何正确地运行?因为print()
声明为virtual
,a
是一个多态类。通过绑定到print
函数指针,您将通过A
指针进行调用,调用方式与:
A* ab = &b;
ab->print();
在上面的
->print
调用中,您将看到多态行为。在代码中也是如此。如果你问我,这是件好事。至少,大多数时候是这样。:) 这与普通成员函数指针的工作方式相同。以下操作产生相同的输出:
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做了任何不同的事情,那将是令人惊讶的,因为它们可能将这些指向成员函数的指针存储在引擎盖下。哦,当然没有提到这些指针是没有链接的。如果使用Tr1,它应该被标记为C++。0x@John这个代码是在GCC 4.2下编译的C++,不接触C++ 0x。请你澄清一下你的立场好吗?@fbrereto:
tr1
名称空间中的所有内容都来自C++0x标准草案中的标准库提案;特别是技术报告1中的内容@fbereto:如果您使用的是TR1工具,那么根据定义,您使用的是C++0x。Tr1是C++0x@John:否,TR1不是C++0x。TR1是2005年提出的一套图书馆。C++0x是该标准的新修订版,有望于2011年发布。Rt1库不是C++标准库的一部分,这就是为什么它们都在std
命名空间)。您不仅绑定到print(),后者的行为与此处所述的多态性相同,还绑定到要从中调用它的对象。对象的类型因为第二个绑定而起作用。当我看到这个问题时,我想到的第一件事就是那篇文章!非常有趣和彻底。
int main ()
{
A a;
B b;
typedef void (A::*fp)();
fp p = &A::print;
(a.*p)(); // prints A
(b.*p)(); // prints B
}