C 处理类模板及其类型的方法是什么?

What is the C++ way to deal with class templates and their types?

本文关键字:类型 方法 是什么 处理      更新时间:2023-10-16

我以为我已经理解了C 中类模板的概念,但是查看我的代码,我不再确定了。说我有两个班级,一个非修订父母和一个小时候的模板,这样:

class MyParent
{
    std::string m_Name;
    MyParent(std::string Name) : m_Name(Name) { }
    virtual const std::type_info& GetType() = 0;
};
template <class T>
class MyChild : public MyParent
{
    T m_Var;
    const std::type_info& GetType() override
    { return typeid(m_Var); }
};

现在,在我的代码中,我有一个使用其他类型的MyChild实例的容器,例如:

MyParent* p1 = new MyChild<int>("one");
MyParent* p2 = new MyChild<float>("two");
MyParent* p3 = new MyChild<double>("three");
std::vector<MyParent*> v = {p1, p2, p3};

到目前为止,这很清楚,现在到我的混乱开始的地方。假设我在该向量上有一个迭代的函数,然后它需要对每个元素做一些事情。我刚刚构成的一个例子(我的问题不是关于代码本身,而是如何处理这种情况):

/* ... */
for(auto* p : v)
{
    if(p->GetType() == typeid(int))
    {
        int val = p->m_Var;
        std::list<int> lst = {val, 1, 2, 3};
        if(val >= 0)
            SomeTemplFuncPositive(v * v, lst);  // a template variadic function
        else
            SomeTemplFuncNegative(v * v * -1, lst);
    }
    else if(p->GetType() == typeid(float))
    {
        /* ... now the same block c&p again for float? */
    }
    else if(p->GetType() == typeid(double))
    {
        /* ... and again for double?! */
    }
}
/* ... */

在其他语言中,例如python,例如我只有一个代码块,但是在C 中,在我看来,我需要再次复制float的整个代码块,而double的时间又是另一个时间,等等。。

我不想怪C ,如果那是必须的,那就好了。我只是想知道,当在C 中使用这样的构建体时,这确实是正确的方法?

需要调整您的 virtual -ity:

class MyParent
{
    std::string m_Name;
    MyParent(std::string Name) : m_Name(Name) { }
    virtual void doSomething()=0;
};
template <class T>
class MyChild : public MyParent
{
    T m_Var;
    void doSomething() override
    {
        T val = this->m_Var;
        std::list<T> lst = {val, 1, 2, 3};
        if (val >= 0)
            SomeTemplFuncPositive(v * v, lst);
        else
            SomeTemplFuncNegative(v * v * -1, lst);
    }
};

现在,您通过其基类调用doSomething()

for(auto* p : v)
{
    p->doSomething();
}

一切都完全写了一次。

如果您需要从基础到孩子,则代码很可能是错误的(至少在C 中)。当您将指针存储到衍生物中时,您应该确保您不需要公开访问其特定成员(但虚拟方法仍然可以这样做)。在这种情况下,应在派生中声明列表,并将T作为模板参数。

另外,您不需要getType函数,可以使用dynamic_cast<DerivativeClass*>(baseClassPtr),如果铸件可以,则可以返回适当的指针,如果无法完成铸造,则可以使用Nullptr。

相关文章: