2010-11-26 4 views
2

implementieren (bezogen auf eine vorherige unanswered question Ich fragte). Ich möchte eine Funktion implementieren, die nur mit Vektoren verwandter Klassen als Parameter aufgerufen werden kann.Wie Funktion mit Vektor der abgeleiteten Klassen als Parameter

Für eq

wenn wir

class A; 
class B: public A; 
class C: public A; 
class D 

then it should be possible to call function with vector<A*>,vector<B*> or 
vector <C*> but not vector <D*> 

Irgendwelche Vorschläge

Antwort

1

Ich denke, man bereits versucht, eine Methode, wie

void doSomething(std::vector<A*>& things) 
{ 
} 

und versuchen zu schaffen Do not Pass

std::vector<B*> bList = ...; 
doSomething(bList); 

richtig?

Warum beschweren sich die Compiler? Weil es keinen Sinn ergeben würde. Bedenken Sie, dass doSomething()

things.push_back(new C()); 

Dies kann nicht als „Dinge“ arbeiten ein std::vector<B*> tatsächlich zu tun versucht. Wenn es jedoch std::vector<A*> wäre, würde push_back funktionieren.

Was können wir daraus lernen? Was Sie versuchen, macht nur Sinn, wenn Sie nur vom Vektor lesen, jedoch ist Vektor kein Read-Only-Container.

Ein einfacher Wrapper zeigt eine mögliche Lösung (der Wrapper kann natürlich an Ihre Bedürfnisse angepasst werden). Ich muss jedoch darauf hinweisen, dass die Verwendung von virtuellen Methoden zu Leistungseinbußen führen kann.

class A {}; 
class B : public A {}; 

template <class Base> 
class AbstractVectorWrapper 
{ 
public: 
    virtual size_t size() const = 0; 
    virtual Base* getElementAt(int index) const = 0; 
}; 
template <class Base, class Derived> 
class VectorWrapper : public AbstractVectorWrapper<Base> 
{ 
private: 
    std::vector<Derived*> m_vector; 
public: 
    explicit VectorWrapper(std::vector<Derived*> const& vector) 
     : m_vector(vector) 
    { 
    } 
    virtual size_t size() const 
    { 
     return m_vector.size(); 
    } 
    virtual Base* getElementAt(int index) const 
    { 
     return m_vector[index]; 
    } 
}; 

void doSomething(AbstractVectorWrapper<A> const& wrapper) 
{ 
    for (size_t i=0;i<wrapper.size();i++) 
    { 
     A* a = wrapper.getElementAt(i); 
    } 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::vector<A*> as; 
    std::vector<B*> bs; 
    doSomething(VectorWrapper<A,B>(bs)); 
    doSomething(VectorWrapper<A,A>(as)); 


    return 0; 
} 
+0

wusste ich, dass es nicht möglich ist, daher die Frage :-) – Gaurav

+0

sagte ich, warum es nicht, es kann nicht funktionieren, die nicht, daher meine Antwort :-). – Philipp

+0

hinzugefügt eine mögliche Lösung – Philipp

1

Ist duck-typing gut genug für Sie? Betrachten Sie diesen Code

template <class T> 
void my_function (std::vector <T*> const &values) { 
    // Use features of A* here 
} 

Dies wird scheitern zu kompilieren, wenn Sie Funktionen, die Zeiger auf T nicht unterstützen. Durch die Verwendung der Funktionen von A sollte sichergestellt werden, dass die Zeiger auf B und C auch wie erwartet funktionieren. Es wäre jedoch möglich, diese Funktion mit Vektoren von D * aufzurufen, vorausgesetzt, die Schnittstelle entspricht dem, was my_function versucht zu tun.

Verwandte Themen