2013-10-08 42 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 ...)