2010-11-07 46 views
0

有沒有辦法爲所有派生類自動執行此操作,我不必爲所有嵌套類創建函數applyPack。如何做到這一點自動?

這是一張我的代碼:

/** every class has registered id with this function */ 
template<typename T> 
uint getID() { 
    static uint id = registerClass<T>(); 
    return id; 
} 

class TemplatesPack { 
public: 
    template<typename T> 
    typename T::Template get(); 
}; 

class Object { 
public: 
    virtual void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object>()); }; 
}; 

class Object2: public Object { 
public: 
    void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object2>()); }; 
}; 

class Object3: public Object { 
public: 
    void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object3>()); }; 
}; 

class Object4: public Object2 { 
public: 
    void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object4>()); }; 
}; 

我讀過一些關於類型的特徵,但我不希望有Object類模板。這可以用C++完成,並在類TemplatesPack或C++ 0x中模板化一些函數? s

+3

你真的想做什麼?我不能想到一個用例,你需要在這個問題中試圖做什麼。有可能有更好的方法來實現你的目標。 – 2010-11-07 11:10:43

回答

5

編輯:
改變了答案,使對象不變。

template<class T> 
class Base<T> : public Object 
{ 
public: 
    virtual void applyPack(TemplatePack *p) { this->setTemplate(p->get<T>()); }; 
}; 

class Object2 : public Base<Object2> 
{ 
    // ... 
}; 

編輯:爲Object4的情況下,也許下面將幫助:

template<class S, class D> 
class Base<S, D> : public S 
{ 
public: 
    virtual void applyPack(TemplatePack *p) { this->setTemplate(p->get<D>()); }; 
}; 

class Object2 : public Base<Object, Object2> { /* ... */ }; 

class Object3 : public Base<Object, Object3> { /* ... */ }; 

class Object4 : public Base<Object2, Object4> { /* ... */ }; 
+0

-1:OP不希望'Object'成爲模板類。 – 2010-11-07 10:51:37

+1

-1:OP說他不想模板這個類,更糟糕的是,這種方法意味着'Object2','Object3'等將處於不相關的類層次結構中! – 2010-11-07 10:52:17

+0

@downvoters:的確如此。我已經調整了答案。 – Vlad 2010-11-07 10:57:30

1

你可以使用虛擬繼承和顯性規則,如果你不希望模板化Base

template<typename Derived, typename Base = void> 
struct applyer : virtual applyer<Base, typename Base::base_type> { 
    virtual void applyPack(TemplatesPack *p) { 
    dynamic_cast<Derived*>(this)->setTemplate(p->get<Derived>()); 
    }; 

    typedef Base base_type; 
}; 

template<typename Derived> 
struct applyer<Derived, void> { 
    virtual void applyPack(TemplatesPack *p) { 
    dynamic_cast<Derived*>(this)->setTemplate(p->get<Derived>()); 
    }; 
}; 

現在您可以按如下方式操作

class Object : virtual public applyer<Object> { 

}; 

class Object2: public Object, virtual public applyer<Object2, Object> { 

}; 

class Object3: public Object, virtual public applyer<Object3, Object> { 

}; 

第二個參數分別是直接基類,如果沒有的話可以省略。例如,如果你從Object3派生,你需要這樣做,如下所示

class Object3_1: public Object3, virtual public applyer<Object3_1, Object3> { 

}; 
+0

這會在每個對象上花費額外的內存嗎? – kravemir 2010-11-07 11:07:34

+0

我可以在更多次使用Object4派生類嗎? – kravemir 2010-11-07 11:08:38

+0

@Miro你需要測試它是否使用更多的內存。我不知道。它適用於Object4(在我的示例中稱爲「Object3_1」,因爲我在修改問題之前編寫了它)。 – 2010-11-07 11:14:41