2016-12-16 64 views
2

我想覆蓋派生類中的模板方法從基類的虛擬方法;只是想知道是否有任何聰明的方法或解決方法,使這成爲可能。是否可以使用派生類中的模板方法覆蓋虛擬方法?

#include <iostream> 
using namespace std; 

struct A 
{ 
    virtual void AF(int i) 
    { 
     std::cout << "Function in A" << std::endl; 
    } 

    virtual void af(int i) 
    { 
     std::cout << "Function in A" << std::endl; 
    } 
}; 

struct B 
{ 
    virtual void BF(int i) 
    { 
     std::cout << "Function in B" << std::endl; 
    } 

    virtual void bf(int i) 
    { 
     std::cout << "Function in B" << std::endl; 
    } 
}; 

template<bool IS_A> 
struct C : public A, public B 
{ 
    template<class I> 
    typename std::enable_if<std::is_same<int, I>::value && IS_A,void>::type AF(I i) 
    { 
     std::cout << "Function override from A in C" << std::endl; 
    } 
    template<class I> 
    typename std::enable_if<std::is_same<int, I>::value && !IS_A,void>::type BF(I i) 
    { 
     std::cout << "Function override from B in C" << std::endl; 
    } 
    template<class I> 
    void af(I i) 
    { 
     std::cout << "Function override from A in C" << std::endl; 
    } 
    template<class I> 
    void bf(I i) 
    { 
     std::cout << "Function override from B in C" << std::endl; 
    } 
}; 


int main() { 
    int i(0); 
    { 
     A * a = new C<true>(); 
     a->AF(i); 
     a->af(i); 
    } 
    { 
     B * b = new C<false>(); 
     b->BF(i); 
     b->bf(i); 
    } 
    return 0; 
} 

輸出是:

  • 功能在//希望這是功能覆蓋從A用C
  • 功能在//希望這是功能覆蓋從A用C
  • 功能的乙//希望這是功能從重寫中的B下在乙
  • 功能//想這在C
是功能覆蓋從乙

謝謝。

+1

如果只爲A和B的相同'int'啓用它們,那麼對C :: AF和C :: BF使用模板的目的是什麼? –

回答

0

可以使用CRTP成語這樣做:

#include <iostream> 
#include<type_traits> 

struct A 
{ 
    virtual void AF(int) 
    { 
     std::cout << "Function in A" << std::endl; 
    } 

    virtual void af(int) 
    { 
     std::cout << "Function in A" << std::endl; 
    } 
}; 

struct B 
{ 
    virtual void BF(int) 
    { 
     std::cout << "Function in B" << std::endl; 
    } 

    virtual void bf(int) 
    { 
     std::cout << "Function in B" << std::endl; 
    } 
}; 

template<typename D> 
struct CRTP: public A, public B 
{ 
    template<typename I> void CAF(I i) { A::AF(i); } 
    template<typename I> void af(I i) { A::af(i); } 
    template<typename I> void CBF(I i) { B::BF(i); } 
    template<typename I> void cbf(I i) { B::bf(i); } 

    void AF(int i) override { static_cast<D*>(this)->CAF(i); } 
    void af(int i) override { static_cast<D*>(this)->caf(i); } 
    void BF(int i) override { static_cast<D*>(this)->CBF(i); } 
    void bf(int i) override { static_cast<D*>(this)->cbf(i); } 
}; 

template<bool IS_A> 
struct C : CRTP<C<IS_A>> 
{ 
    template<class I> 
    void CAF(I i) 
    { 
     std::cout << "Function override from A in C" << std::endl; 
    } 
    template<class I> 
    void CBF(I i) 
    { 
     std::cout << "Function override from B in C" << std::endl; 
    } 
    template<class I> 
    void caf(I i) 
    { 
     std::cout << "Function override from A in C" << std::endl; 
    } 
    template<class I> 
    void cbf(I i) 
    { 
     std::cout << "Function override from B in C" << std::endl; 
    } 
}; 

int main() 
{ 
    int i(0); 
    { 
     A * a = new C<true>(); 
     a->AF(i); 
     a->af(i); 
    } 
    { 
     B * b = new C<false>(); 
     b->BF(i); 
     b->bf(i); 
    } 
    return 0; 
} 
+0

有一個區別:如果在C中4個函數中的一個沒有被覆蓋,這不是A或B中被調用的那個函數,這是CRTP的,你有一個無限遞歸! –

+0

@ O'Neil更新。沒有更多的無限遞歸。 – skypjack

0

首先,根據IS_A「啓用/禁用」成員函數,你可以定義的C既truefalse專業:

template <bool IS_A> 
struct C; 

template <> 
struct C<true> : A, B 
{ 
    // functions only defined for IS_A == true 
}; 

template <> 
struct C<false> : A, B 
{ 
    // functions only defined for IS_A == false 
} 

並且通過模板介紹重寫,您可以覆蓋A和B中您稱爲模板的那些:

void af(int i) override { af<int>(i); } 
void bf(int i) override { bf<int>(i); }