Domanda

Mi chiedo, a causa di un problema in cui mi imbatto, è possibile creare un vettore di puntatori? E se sì, come? In particolare riguardo all'uso di iteratori e .begin () con esso, cioè: Come trasformerei questo vettore in un vettore di puntatori:

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();
}
È stato utile?

Soluzione 2

vector <c> cvect non è un vettore di puntatori. È un vettore di oggetti di tipo c. Vuoi vector <c*> cvect. e probabilmente vuoi:

cvect.push_back( new c );

E poi, dato un iteratore, vuoi qualcosa del tipo:

(*it)->func();

Ovviamente, è molto probabile che tu non abbia voluto un vettore di puntatori in primo luogo ...

Altri suggerimenti

Certo.

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

Cose da tenere a mente:

Dovrai pulire dopo te stesso se usi la memoria allocata in modo dinamico come ho fatto nel mio esempio

per esempio:.

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

Questo può essere semplificato usando un vettore di shared_ptr s (come boost::shared_ptr). Non tentare di utilizzare std::auto_ptr per questo, non funzionerà (non verrà nemmeno compilato).

Un'altra cosa da tenere a mente, dovresti evitare di usare < per confrontare gli iteratori nel tuo ciclo quando possibile, funzionerà solo per gli iteratori che modellano un iteratore ad accesso casuale, il che significa che non puoi cambiare il tuo codice in usare ad es a std::list.

Sì, è possibile, e in effetti è necessario utilizzare i puntatori se si intende che il proprio vettore contenga oggetti di un'intera gerarchia di classi anziché di un singolo tipo. (Il mancato utilizzo dei puntatori comporterà il temuto problema di taglio degli oggetti - tutti gli oggetti sono silenziosi convertito in un tipo di classe base. Questo non è diagnosticato dal compilatore e quasi certamente non è quello che vuoi.)

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();
}

Nota che con un vettore di puntatori, devi fare la tua gestione della memoria , quindi fai molta attenzione - se utilizzerai oggetti locali (come sopra), non devono cadere di portata prima del contenitore. Se si utilizzano i puntatori agli oggetti creati con new, è necessario delete manualmente prima che il contenitore venga distrutto. In questo caso dovresti assolutamente considerare di utilizzare i puntatori intelligenti, come smart_ptr fornito da Boost .

Sì, certo.

// 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;
}

Nota la dichiarazione di vector<c*> cvect e l'uso di cvect.push_back(&cobj).

Dal codice fornito, stai usando iteratore in modo sbagliato. Per accedere al membro che un iteratore punta a te devi usare *citer invece di citer da solo.

Hai creato vector<c*> per un vettore di puntatori. Quindi utilizzare new per allocare la memoria per gli oggetti c e spingerli nel vettore. Inoltre, non dimenticare che devi delete te stesso e vector.clear () non rilascerà la memoria allocata per gli oggetti c. Devi memorizzare c come vettore di puntatori qui, altrimenti la chiamata alla funzione virtuale non funzionerà.

Prova Boost Pointer Container Library . Ha diversi vantaggi rispetto al vettore regolare di puntatori, come:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top