¿Es posible crear un vector de punteros?

Solo me pregunto, debido a un problema que estoy encontrando, ¿es posible crear un vector de punteros? Y si es así, ¿cómo? Específicamente sobre el uso de iteradores y .begin () con él, es decir: ¿Cómo convertiría este vector en un vector de punteros:

class c { void virtual func(); }; class sc:public c { void func(){cout<<"using func";} }; sc cobj; vectorcvect cvect.push_back(cobj); vector::iterator citer for(citer=cvect.begin();citerfunc(); } 

Por supuesto.

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

Cosas a tener en cuenta:

Tendrás que limpiar después de ti mismo si usas memoria asignada dinámicamente como lo hice en mi ejemplo

p.ej:

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

Esto se puede simplificar utilizando un vector de shared_ptr s (como boost::shared_ptr ). No intentes usar std::auto_ptr para esto, no funcionará (ni siquiera comstackrá).

Otra cosa a tener en cuenta, debe evitar usar < para comparar iteradores en su bucle cuando sea posible, solo funcionará para los iteradores que modelan un iterador de acceso aleatorio, lo que significa que no puede cambiar su código para usar, por ejemplo, un std::list .

vector cvect no es un vector de punteros. Es un vector de objetos de tipo c. Quieres vector cvect . y el que probablemente quieras:

 cvect.push_back( new c ); 

Y luego, dado un iterador, quieres algo como:

 (*it)->func(); 

Por supuesto, es muy probable que no quisieras un vector de punteros en primer lugar …

Sí, es posible, y de hecho es necesario usar punteros si pretende que su vector contenga objetos de una jerarquía de clases completa en lugar de un solo tipo. (Si no se utilizan los punteros, se producirá el temido problema de la segmentación de objetos : todos los objetos se convierten de forma silenciosa al tipo de clase base. El comstackdor no diagnostica esto y es casi seguro que no es lo que desea).

 class c { void virtual func(); }; class sc:public c { void func(){cout<<"using func";} }; sc cobj; vector cvect; // Note the type is "c*" cvect.push_back(&cobj); // Note the "&" vector::iterator citer; for(citer=cvect.begin();citer != cvect.end();citer++) // Use "!=" not "<" { (*citer)->func(); } 

Tenga en cuenta que con un vector de punteros, debe realizar su propia administración de memoria , así que tenga mucho cuidado: si va a utilizar objetos locales (como se indica anteriormente), no deben quedar fuera del scope antes de que lo haga el contenedor. Si utiliza punteros a objetos creados con new , deberá delete manualmente antes de destruir el contenedor. Debe considerar absolutamente utilizar punteros inteligentes en este caso, como el smart_ptr proporcionado por Boost .

Si seguro.

 // TestCPP.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include  #include  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 cvect; cvect.push_back(&cobj); vector::iterator citer; for(citer=cvect.begin();citerfunc(); } return 0; } 

Tenga en cuenta la statement de vector cvect y el uso de cvect.push_back(&cobj) .

A partir del código proporcionado, está utilizando iterador de forma incorrecta. Para acceder al miembro al que apunta un iterador, debe usar *citer lugar de citer solo.

Ha creado el vector para un vector de punteros. Luego use new para asignar la memoria para los objetos c y empujarlos en vector. Además, no olvide que debe borrarse usted mismo y vector.clear () no liberará la memoria asignada para los objetos c. Debe almacenar c como un vector de punteros aquí, de lo contrario, la llamada a la función virtual no funcionará.

Pruebe la biblioteca de contenedores de punteros Boost . Tiene varias ventajas sobre el vector regular de punteros, como:

 my_container.push_back( 0 ); // throws bad_ptr ptr_vector pvec; std::vector vec; ( *vec.begin() )->foo(); // call X::foo(), a bit clumsy pvec.begin()->foo(); // no indirection needed