2015-05-03 60 views
4

是否可以在C++14中執行此類操作。我有一個基類如下:將函數注入子類

#include <iostream> 

class AbstractElement; 
class ConcreteElement; 
class SuperConcreteElement; 

class B 
{ 
public: 
    void bar(AbstractElement*) 
    { 
     std::cout << "Abstract element" << std::endl; 
    } 

    void bar(ConcreteElement*) 
    { 
     std::cout << "Concrete element" << std::endl; 
    } 

    void bar(SuperConcreteElement*) 
    { 
     std::cout << "Super concrete element" << std::endl; 
    } 
}; 

class AbstractElement 
{ 
public: 
    virtual void foo() = 0; 
}; 

class ConcreteElement : public AbstractElement 
{ 
private: 
    B _b; 
public: 
    void foo() 
    { 
     _b.bar(this); //1 
    } 
}; 

class SuperConcreteElement : public AbstractElement 
{ 
private: 
    B _b; 
public: 
    void foo() 
    { 
     _b.bar(this); //2 
    } 
}; 

int main() 
{ 
    AbstractElement *e = new ConcreteElement(); 
    e -> foo(); //Prints Concrete element 
} 

正如你可以看到在//1//2,函數體是完全相似的。但由於取決於this的靜態類型,我無法將其完全移入基類。儘管如此,我並不想每次需要添加AbstractElement的另一個子類時都會寫出完全相同的代碼。所以,我需要某種機制爲我們提供將代碼注入函數的功能。

只要馬科斯不是非常理想的解決方案,我想問一些可以在C++14中解決這個問題的技巧。

回答

1

是,能夠使用CRTP

#include <iostream> 

class AbstractElement; 
class ConcreteElement; 
class SuperConcreteElement; 

class B 
{ 
public: 
    void bar(AbstractElement*) 
    { 
     std::cout << "Abstract element" << std::endl; 
    } 

    void bar(ConcreteElement*) 
    { 
     std::cout << "Concrete element" << std::endl; 
    } 

    void bar(SuperConcreteElement*) 
    { 
     std::cout << "Super concrete element" << std::endl; 
    } 
}; 

class AbstractElement 
{ 
public: 
    virtual void foo() = 0; 
}; 

template <class T> 
class CRTPAbstractElement : public AbstractElement 
{ 
    B _b; 
public: 
    virtual void foo() 
    { 
     T* t = dynamic_cast<T *>(this); 
     _b.bar(t); 
    } 
}; 

class ConcreteElement : public CRTPAbstractElement<ConcreteElement> 
{ 
}; 

class SuperConcreteElement : public CRTPAbstractElement<SuperConcreteElement> 
{ 
}; 

int main() 
{ 
    AbstractElement *e = new ConcreteElement(); 
    e -> foo(); //Prints Concrete element 
} 

通過增加一箇中間CRTP類我們能夠一個指針轉換爲基類的指針派生類。從而解決代碼重複的問題。

+0

很酷,實際上我懷疑模板在這裏會有幫助,但不知道如何使用它。 – user3663882