Frage

Nur frage mich, aufgrund eines Problems in Ich betreibe, ist es möglich, einen Vektor von Zeigern zu erstellen? Und wenn ja, wie? Insbesondere in Bezug auf Iteratoren und .BEGIN () mit ihm, das heißt mit: Wie würde ich diesen Vektor in einen Vektor von Zeigern drehen:

class c
{
     void virtual func();
};

class sc:public c
{
     void func(){cout<<"using func";}
};

sc cobj;

vector<c>cvect
cvect.push_back(cobj);
vector<c>::iterator citer

for(citer=cvect.begin();citer<cvect.end();citer++)
{
     citer->func();
}
War es hilfreich?

Lösung 2

vector <c> cvect ist kein Vektor von Zeigern. Es ist ein Vektor von Objekten des Typs c. Sie wollen vector <c*> cvect. und die Sie wahrscheinlich wollen:

cvect.push_back( new c );

Und dann, da ein Iterator, Sie wollen so etwas wie:

(*it)->func();

Natürlich, es ist ziemlich wahrscheinlich, Sie nicht einen Vektor von Zeigern in erster Linie wollten ...

Andere Tipps

Klar.

vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
  (*citer)->func();
}

Dinge im Auge zu behalten:

Sie werden nach Ihrer selbst zu bereinigen müssen, wenn Sie dynamisch zugewiesenen Speicher verwenden, wie ich in meinem Beispiel tat

z.

 for(...) { delete *i; }

Dies kann durch Verwendung eines Vektors von shared_ptrs vereinfacht werden (wie boost::shared_ptr). Versuchen Sie nicht, std::auto_ptr dafür zu verwenden, es wird nicht funktionieren (wird nicht einmal kompilieren).

Eine andere Sache im Auge zu behalten, sollten Sie vermeiden < mit Iteratoren in der Schleife zu vergleichen, wenn möglich, wird es nur für Iteratoren arbeiten, die einen Direktzugriffs Iterator Modell, das bedeutet, dass Sie Ihren Code nicht ändern aus kann beispielsweise verwendet werden ein std::list.

Ja, es ist möglich, und in der Tat ist es notwendig Zeiger zu verwenden, wenn Sie Ihre Vektor beabsichtigen Objekte aus einer ganzen Klassenhierarchie zu enthalten, anstatt eines einzelnen Typs. (Failing Zeiger zu verwenden, in die gefürchtete Problem der Aufschneiden - alle Objekte sind still konvertierte Typ Basisklasse. Dieser vom Compiler nicht diagnostiziert, und ist mit ziemlicher Sicherheit nicht das, was Sie wollen.)

class c
{
     void virtual func();
};

class sc:public c
{
     void func(){cout<<"using func";}
};

sc cobj;

vector<c*> cvect;             // Note the type is "c*"
cvect.push_back(&cobj);       // Note the "&"
vector<c*>::iterator citer;

for(citer=cvect.begin();citer != cvect.end();citer++)   // Use "!=" not "<"
{
     (*citer)->func();
}

Beachten Sie, dass mit einem Vektor von Zeigern, Sie müssen Ihre eigene Speicherverwaltung tun, so sehr vorsichtig sein - wenn Sie lokale Objekte (wie oben) verwendet werden, müssen sie nicht herausfallen der Umfang, bevor der Behälter der Fall ist. Wenn Sie Zeiger auf Objekte mit new erstellt verwenden, müssen Sie sie manuell delete, bevor der Behälter zerstört wird. Sie sollten unbedingt mit Smart-Pointer in diesem Fall prüfen, wie die smart_ptr bereitgestellt von Boost .

Ja, sicher.

// TestCPP.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <vector>


using namespace std;

class c
{
public:
    void virtual func() = 0;
};

class sc:public c
{
public:
    void func(){cout<<"using func";}
};

int _tmain(int argc, _TCHAR* argv[])
{
    sc cobj;

    vector<c*> cvect;
    cvect.push_back(&cobj);
    vector<c*>::iterator citer;

    for(citer=cvect.begin();citer<cvect.end();citer++)
    {
        (*citer)->func();
    }

    return 0;
}

Bitte beachten Sie die Deklaration von vector<c*> cvect und die Verwendung von cvect.push_back(&cobj).

Aus dem Code zur Verfügung gestellt, die Sie verwenden Iterator in einer falschen Weise. Für den Zugriff auf das Element ein Iterator zeigt auf Sie *citer statt citer allein verwenden.

Sie haben erstellen vector<c*> für einen Vektor von Zeigern. Dann new verwendet die Speicher für c Objekte zuzuweisen und sie in dem Vektor schieben. Auch vergessen Sie nicht, dass Sie sich selbst und vector.clear delete haben () nicht die für c-Objekte zugewiesenen Speicher freigeben. Sie haben hier c als Vektor von Zeigern zu speichern, andernfalls wird der Anruf an die virtuelle Funktion wird nicht funktionieren.

Versuchen Sie Boost-Pointer Container-Bibliothek . Es hat mehrere Vorteile gegenüber regulären Vektor von Zeigern, wie:

my_container.push_back( 0 );            // throws bad_ptr 
ptr_vector<X> pvec; 
std::vector<X*> vec;
( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
pvec.begin()->foo();     // no indirection needed
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top