2011-08-04 26 views
37

Tengo un puntero a un vector. Ahora, ¿cómo puedo leer el contenido del vector a través del puntero? Sé que esta es una pregunta básica, pero no puedo encontrar una respuesta para el mismo. (C++)Puntero a un Vector

+7

¿Qué has intentado hasta ahora? ¿Puedes proporcionar algún código para que podamos tener algo concreto de qué hablar? – Nate

+3

¿Estás seguro de que deseas utilizar un puntero a un vector? Puede tener más sentido usar una referencia. Ver mi publicación a continuación. –

Respuesta

51

Hay muchas soluciones, aquí hay unos pocos que he llegado con:

int main(int nArgs, char ** vArgs) 
{ 
    vector<int> *v = new vector<int>(10); 
    v->at(2); //Retrieve using pointer to member 
    v->operator[](2); //Retrieve using pointer to operator member 
    v->size(); //Retrieve size 
    vector<int> &vr = *v; //Create a reference 
    vr[2]; //Normal access through reference 
    delete &vr; //Delete the reference. You could do the same with 
       //a pointer (but not both!) 
} 
+0

La referencia es un mal consejo, ya que 'new' podría return 0. –

+0

@Don Reba - En realidad no; en la mayoría de los compiladores se lanza una excepción: http://stackoverflow.com/questions/550451/will-new-return-null-in-any-case – Schnommus

+0

Además, si 'new' ** did ** return 0, ** todas ** las operaciones en los punteros serían malas, no solo la inicialización de referencia. – Schnommus

2

Hay muchas soluciones. Por ejemplo, puede usar el método at().

* Supuse que usted busca un operador equivalente al [].

+0

, pero ¿cómo saber la cantidad de elementos en el vector? – Pavan

+1

@ user815961 'v-> size()' devuelve la cantidad de elementos en el vector – Praetorian

12

acceder a ella como cualquier otro valor del puntero:

std::vector<int>* v = new std::vector<int>(); 

v->push_back(0); 
v->push_back(12); 
v->push_back(1); 

int twelve = v->at(1); 
int one = (*v)[2]; 

// iterate it 
for(std::vector<int>::const_iterator cit = v->begin(), e = v->end; 
    cit != e; ++cit) 
{ 
    int value = *cit; 
} 

// or, more perversely 
for(int x = 0; x < v->size(); ++x) 
{ 
    int value = (*v)[x]; 
} 

// Or -- with C++ 11 support 
for(auto i : *v) 
{ 
    int value = i; 
} 
+1

up'd para "como cualquier otro puntero". No entiendo la pregunta. Usted tiene un puntero, entonces usa 'thing-> member' en lugar de' thing.member', y esa es la única diferencia (en el 99% de los casos, etc.) –

11
vector<int> v; 
v.push_back(906); 
vector<int> * p = &v; 
cout << (*p)[0] << endl; 
5

Se puede acceder a los métodos de iterador directamente:

std::vector<int> *intVec; 
std::vector<int>::iterator it; 

for(it = intVec->begin(); it != intVec->end(); ++it) 
{ 
} 

Si desea que el operador de matriz de acceso, tendría para desmarcar el puntero. Por ejemplo:

std::vector<int> *intVec; 

int val = (*intVec)[0]; 
-3

La forma más fácil utilizarlo como matriz es utilizar vector::data() miembro.

+1

La razón por la que utiliza un vector es abstraer la implementación subyacente (matriz contigua) detrás de él. Esto está yendo en contra de los principios orientados a objetos, por no mencionar que es extremadamente ineficiente porque está asignando una matriz entera nueva de tamaño n, cuando podría usar vec-> at (índice). Sin mencionar que esto no tiene absolutamente nada que ver con la pregunta original del póster porque no estás usando un puntero a un vector en ninguna parte. –

+0

Estaba dando un ejemplo, si queremos saber el tipo subyacente, podemos usar vector :: value_type. pero está estáticamente interpretado. el punto que quería transmitir es que data() es el miembro que obtiene el puntero subyacente. Y esa era su pregunta. – sarat

+0

No, la pregunta era si el 'vector' se podía leer a través de un puntero. No veo nada en el OP que indique algo más profundo que eso. –

11

¿Tiene un puntero a un vector porque así es como lo ha codificado? Es posible que desee reconsiderar esto y utilizar una referencia (posiblemente const). Por ejemplo:

#include <iostream> 
#include <vector> 

using namespace std; 

void foo(vector<int>* a) 
{ 
    cout << a->at(0) << a->at(1) << a->at(2) << endl; 
    // expected result is "123" 
} 

int main() 
{ 
    vector<int> a; 
    a.push_back(1); 
    a.push_back(2); 
    a.push_back(3); 

    foo(&a); 
} 

Si bien este es un programa válido, el estilo general C++ es pasar un vector por referencia en lugar de puntero. Esto será igual de eficiente, pero luego no tendrá que lidiar con punteros posiblemente nulos y asignación/limpieza de memoria, etc. Use una referencia constante si no va a modificar el vector, y una referencia no constante si necesitas hacer modificaciones

Aquí está la versión referencias del programa anterior:

#include <iostream> 
#include <vector> 

using namespace std; 

void foo(const vector<int>& a) 
{ 
    cout << a[0] << a[1] << a[2] << endl; 
    // expected result is "123" 
} 

int main() 
{ 
    vector<int> a; 
    a.push_back(1); 
    a.push_back(2); 
    a.push_back(3); 

    foo(a); 
} 

Como se puede ver, toda la información contenida dentro de un serán pasados ​​a la función foo, pero no va a copiar un valor completamente nuevo, ya que se pasa por referencia. Por lo tanto, es tan eficiente como pasar por un puntero, y puede usarlo como un valor normal en lugar de tener que descubrir cómo usarlo como puntero o tener que desreferenciarlo.

+0

Esto puede ser un comentario estúpido. Pero dado que solo usa el método at, ¿hay alguna ventaja en utilizar la sintaxis (* a) [1]? Personalmente, me gusta que, dado que me diluya, refleje mejor mis intereses y esto me facilita la lectura del código (con ventajas me refiero a un aumento significativo del rendimiento en al menos un caso). – patrik

Cuestiones relacionadas