2011-12-28 12 views
15
/* bar.h */ 
class bar{ 
    /* standard stuff omitted */ 
    std::vector<my_obj*> foo; 
}; 

/* bar.cpp */ 
bar::bar(){ 
    // foo = new std::vector<my_obj*>(); <-- why don't I need this line?? 
    foo.push_back(new my_obj()); 
} 

¿Por qué es que esto funciona sin asignar primero foo una nueva instancia de std :: vector?¿por qué no es necesario usar "nuevo" para inicializar std :: vector?

+0

Lo que ellos dijeron. Además, no puedo recomendar 'foo.push_back (new my_obj());' porque ¿dónde vas a liberar la memoria allí? –

Respuesta

33

Porque C++ no es C#/Java.

std::vector<my_obj*> foo; 

Esta es una definición de un objeto , no una referencia como en C#/Java. Un objeto es una instancia viviente de un tipo.

new std::vector<my_obj*>() 

Esta expresión devuelve un puntero. Devuelve un std::vector<my_obj*>*, que es no del mismo tipo que foo (la * al final es lo que los hace diferente). foo es un objeto, std::vector<my_obj*>* es un puntero a un objeto.

objetos (en lugar de punteros o referencias) tienen tiempos de vida específicos. Si crea un puntero a un objeto con new, la duración del objeto apuntado será hasta que llame explícitamente al delete. Si crea un objeto como miembro de otro, la duración de ese objeto interno reflejará (más o menos) la duración del objeto externo. Si crea un objeto en la pila (un parámetro o variable en el alcance de la función), su duración es el alcance actual de ese nombre de variable.

6

Porque bar contiene std::vector, no std::vector *.

Es realmente no es diferente a algo como esto:

class bar 
{ 
    int foo; // No need to create a "new int" 
}; 
1

std :: vector en esta biblioteca no es un puntero

0

std::vector<my_obj *> foo es diferente de std::vector<my_obj *> *foo. El segundo caso requerirá que uses nuevo mientras que el primero no.

2

Debido std::vector lo hace por usted :) Usted no tiene un puntero a std::vector, usted es simplemente la creación de un objeto de tipo std::vector, que asigna internamente memoria para usted.

0

No es necesario utilizar new en foo, ya que foo es un vector, no un puntero a una vector (es decir std::vector<my_obj*> *foo).

Si viene de Java o C#, es posible que desee considerar el uso de std::vector<my_obj> (un vector de objetos) en lugar de un vector de punteros. Realmente depende de lo que quieras hacer.

3

Porque foo es un objeto, no un puntero.

std::vector<my_obj*> // This is an object 
std::vector<my_obj*> * // This is a pointer to an object 
        ^^^ // Notice the extra star. 

Nueva rerturns un puntero:

new std::vector<my_obj*>(); // returns std::vector<my_obj*> * 

PS. Tu vector probablemente debería contener objetos, no punteros.

std::vector<my_obj> foo; 
... 
foo.push_back(my_obj()); 

lo contrario, tendrá que eliminar manualmente todos los objetos en el vector cuando se sale del ámbito (cuando el objeto que contiene es destruido). es decir, si desea mantener los punteros en su vector, debe hacer una de las siguientes acciones:

// 1. Manually delete all the elements in the vector when the object is destroyed. 
~bar::bar() 
{ 
    for(std::vector<my_obj*>::iterator loop = foo.begin(); loop != foo.end(); ++loop) 
    { 
     delete (*loop); 
    } 
} 

// 2. Use a smart pointer: 
std::vector<std::shared_ptr<my_obj> > foo; 

// 3. Use a smart container for pointers 
boost::ptr_vector<my_obj> foo 
Cuestiones relacionadas