2016-11-26 20 views
1

我有一种情况,我试图编写一些C++代码来实现,我想我需要使用模板,但我不确定。我认为我对模板的理解不够好,只是想知道我是否在正确的轨道上。我从来没有实现过需要模板的类。C++模板构建未知类实例列表

我有一个基类需要实例化一个新类,并将其存储在列表中供将来访问。需要实例化的类是从具有一个虚拟方法的基类派生的。类实例化后,调用此方法,并将新实例存储在列表中。提供了另一种获取实例化对象的方法。

说虚拟类名为foo:

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

用户将创建一个类吧:

class bar : public foo 
{ 
    public: 
    void process() {}; 
} 

,我认为需要有一个模板类的类:

class Filter<Foo* T> 
{ 
public: 
    // use value junk to derive foo 
    // and put the new instance on a std::list 
    add(Junk* junk); 
    T get(); 

private: 
    std::list<T> mFooList; 
} 

void Filter::add(Junk* junk) 
{ 
    T* foo = new T(); 
    foo.p(junk); 
    mFooList.push_back(foo); 
} 

T* Filter::get() 
{ 
    if(!mFoolist.empty()) 
    { 
     T* res = mFooList.back(); 
     mFooList.pop_back(); 
     return res; 
    } 
    return nullptr; 
} 
+0

你这里有几个问题。 'class Filter '不是声明模板的方法。而'void Filter :: add(垃圾*垃圾)'不会以任何方式使用'垃圾',那么它会如何影响存储值呢?而且'mFooList.pop_back();'是一个'void'函数,所以不会实际返回任何东西。 –

+0

我刚刚忽略了如何使用垃圾作为fir过滤器的系数的细节。我只是认为这会给问题增加不必要的复杂性。 – Nefarious

+0

所以,让我理解你的语法更清晰 - 你想'T'是从'Foo'派生的类型作为模板参数传递给'Filter'类,还是我过度解释你的代码? –

回答

-1

你不需要在这种情况下使用templatevin。在C++中,可以将派生类分配给基类的指针。你可以使用foo指针。

class foo 
{ 
    public: 
    virtual void process(); 
}; 

class bar1: public foo 
{ 
    public: 
    void process(); 
}; 

class bar2 : public foo 
{   
    public: 
    void process(); 
}; 

class filter 
{ 
    private: 
    std::list<foo*> _foos; 

    public: 
    foo* get(); 
    void add(foo* f); 
}; 

void filter::add(foo* f) 
{ 
    _foos.push_back(f); 
} 

foo* filter::get() 
{ 
    if(!_foos.empty()) 
    { 
     return _foos.pop_back(); 
    } 
    return nullptr; 
} 

然后你可以再补充,并得到FOOS和酒吧

filter fil; 
fil.add(new foo()); 
fill.add(new bar1()); 
fill.add(new bar2()); 

foo f = fill.get(); 
while(f != nullptr) 
{ 
    f->process(); 
    delete f; 
    f = fil.get(); 
} 
+1

你应该使用智能指针。 – dani

+0

当用户调用add时,参数是一个不同的类,知道何时定义类过滤器。它是输入类。我希望能够允许用户通过指定一个将按照他们想要的方式处理输入的类来更改过滤器的实现。 – Nefarious

+0

['list :: pop_back'使用不正确](http://en.cppreference.com/w/cpp/container/list/pop_back)。注意'void'返回类型。并注意下划线前缀。 [有时他们的意思比你想象的要多。](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – user4581301