2013-10-08 41 views
1

我想创建一个父类的版本的虚拟和重载函数的一个std ::函数对象,请看下面的例子:使用std ::绑定绑定到一个虚函数的父版本

#include <iostream> 
#include <functional> 

class Parent 
{ 
    public: 

     virtual void func1() 
     { 
      std::cout << "Parent::func1\n"; 
     } 

     virtual void func2() 
     { 
      std::cout << "Parent::func2\n"; 
     } 
}; 

class Child : public Parent 
{ 
    public: 

     // overrides Parent::func1 
     virtual void func1() 
     { 
      std::cout << "Child::func1, "; 
      Parent::func1(); 
     } 

     // overrides Parent::func2 
     virtual void func2() 
     { 
      std::cout << "Child::func2, "; 
      std::function< void() > parent_func2 = std::bind(&Parent::func2, this); 
      parent_func2(); 
     } 
}; 

int main() 
{ 
    Child child; 

    child.func1(); // output: Child::func1, Parent::func1 

    child.func2(); // output: Child::func2, Child::func2, ... 

    return 0; 
} 

虽然对child.func1()的呼叫表现正常,但拨打child.func2()的呼叫成为无限递归,其中parent_func2()似乎呼叫Child::func2(),而不是我想要绑定的Parent::func2()

任何想法如何我可以有parent_func2()真的叫Parent::func2

+4

我不认为你可以直接做到这一点,它仍然只会做一个虚拟调度。一个更好的主意是像'[=] {this-> Parent :: func2(); }'。 – Xeo

+0

为什么在:: std :: bind和Parent :: func1的调用中调用Child :: func2的Parent :: func2不是?即使您的解决方法可能有效,但我想明白为什么会这样。 –

+0

因为虚拟调度仍然完成,所以只能在明确的父函数调用时禁用它,据我所知。 – Xeo

回答

0

你可以写一个小函子做:

struct Parent_func2 
{ 
    void operator()(Parent* p) const 
    { 
    p->Parent::func2(); 
    } 
}; 

并使用

std::function< void() > parent_func2 = std::bind(Parent_func2(), this); 

(考虑这个问题,我想这只是什么XEO提出一个更详细的方式@ Xeo,让你的评论一个答案,你有我的upvote ...)