2010-12-29 10 views
0

Ich erhalte Basisklasse Zeiger Vektor, der abgeleiteten Klasse Zeiger Vektor übergeben werden benötigt, schlagen Sie bitte besten Weg, das gleiche zu tun.Gießen derivedclassptrVector von baseclassptrVec, den besten Weg?

Ein Weg wird

eine neue abgeleitete Klasse Vektors mit der Vektorgröße ptr

Schleife der ankommende Vektor

dynamische Umwandlung der Basiszeiger und füllen den abgeleiteten Vektor Basisklasse erstellen.

Bitte schlagen Sie vor, wenn es eine bessere Möglichkeit gibt zu überzeugen, dass der Vektor für die polymorphen Typen ist.

+0

Sind Sie sicher, dass alle Objekte in der Basisklasse Zeiger sind Klassenobjekte tatsächlich abgeleitet? Andernfalls wird das Casting fehlschlagen. Denken Sie nur darüber nach, was passiert, wenn jemand eine neue abgeleitete Klasse schreibt und einen Zeiger darüber gibt. Ich denke, du solltest dein Design neu interpretieren. – Naveen

+0

Ich lese das zuerst rückwärts. Wie Naveen sagt, ist das, was Sie tun, wahrscheinlich nicht ratsam und bezeichnend, dass es ein besseres Design mit virtuellen Methoden geben könnte. Der andere Weg ... einen Vektor abgeleiteter Klassenzeiger auf einen Vektor von Basisklassenzeigern zu werfen ... ist vernünftig zu wollen, aber in C++ nicht legal, da Vorlagen "Kovarianz" nicht unterstützen: http://stackoverflow.com/ Fragen/3922335/Verweis auf einen stdvector-von-abgeleiteten Klassen-Pointer-as-input-Parameter-to-a-func – HostileFork

Antwort

2

Wenn ich die Frage richtig zu verstehen, müssen Sie die folgende Situation

class Base {}; 
class Derived: public Base {}; 
class Derived2: public Base {}; 

void foo(const vector<Derived*>&); 

void bar() 
{ 
    vector<Base*> baseVec; 

    // Fill baseVec with pointers to Derived objects 

    foo(baseVec); // Does not work 
} 

Das Problem ist, dass, obwohl Base und Derived durch Vererbung verwandt sind, die Typen vector<Base*> und vector<Derived*> sind völlig unabhängig. Es gibt keine Konvertierung zwischen den beiden.
Auch gibt es das zusätzliche Problem, dass baseVec könnte auch Zeiger auf andere abgeleitete Klassen, wie Derived2, und foo kann nicht mit diesen umzugehen.

Die einzigen wirklichen Lösungen sind

  • die in der Frage vor: ein neues vector<Derived*> erstellen und das Auffüllen mit dynamic_cast ed Inhalt des Quellvektors
  • vermeiden, einen Typenkonflikt im Programm hat, so.
1

Ich denke, was Sie ist die rechtliche Art und Weise erwähnt. Wenn Sie den Vektor selbst zu werfen haben, werden einige Assertionsfunktion wie die Ihren Zweck folgende dienen?

struct A { 
    virtual ~A() {} 
}; 

struct B : A {}; 

template< class Derived, class Base > 
vector<Derived> const* dynamic_cast_vector(vector<Base> const& x) 
{ 
    for (typename vector<Base>::const_iterator i = x.begin(), e = x.end(); 
     i != e; 
     ++ i) { 
    if (! dynamic_cast<Derived>(*i)) return 0; 
    } 

    return (vector<Derived> const*) &x; 
} 

int main() 
{ 
    vector< A* > av(1, new A), bv(1, new B); 
    dynamic_cast_vector< B* >(av); // null 
    dynamic_cast_vector< B* >(bv); // ok 
} 

this helps

0

Wenn Sie sicher sind, dass Ihr baseclassptrVector nur derivedclass Zeiger hat, können Sie den C++ Typ umgehen mit der Überprüfung:

derivedclassptrVector = reinterpret_cast<std::vector<derivedclass *> &>(baseclassptrVector); 
Verwandte Themen