2010-11-07 125 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