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

Perché funziona senza prima assegnare a foo una nuova istanza di std :: vector?perché non è necessario utilizzare "nuovo" per inizializzare std :: vector?

+0

Cosa hanno detto. Inoltre, non posso raccomandare 'foo.push_back (new my_obj());' perché dove hai intenzione di liberare la memoria lì? –

risposta

33

Perché C++ non è C#/Java.

std::vector<my_obj*> foo; 

Questa è una definizione di un oggetto , non un riferimento come in C#/Java. Un oggetto è un'istanza vivente di un tipo.

new std::vector<my_obj*>() 

Questa espressione restituisce un puntatore. Restituisce un std::vector<my_obj*>*, che è non dello stesso tipo foo (la * alla fine è ciò che li rende diversi). foo è un oggetto, std::vector<my_obj*>* è un puntatore a un oggetto.

oggetti (piuttosto che puntatori o riferimenti) hanno tempi di vita specifici. Se crei un puntatore a un oggetto con new, la durata dell'oggetto puntato sarà finché non chiami esplicitamente delete. Se crei un oggetto come membro di un altro oggetto, allora la durata dell'oggetto di quell'oggetto interno (più o meno) rispecchierà la vita dell'oggetto esterno. Se si crea un oggetto nello stack (un parametro o una variabile nell'ambito della funzione), la durata è l'ambito corrente del nome di tale variabile.

6

Perché bar contiene un std::vector, non un std::vector *.

E 'davvero non è diverso da qualcosa di simile:

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

std :: vector in questa libreria non è un puntatore

0

std::vector<my_obj *> foo è diverso da std::vector<my_obj *> *foo. Il secondo caso richiederà l'utilizzo di nuovi mentre il primo no.

2

Perché std::vector che fa per voi :) Non è un puntatore a std::vector, si sta semplicemente la creazione di un oggetto di tipo std::vector, che assegna internamente memoria per voi.

0

Non è necessario utilizzare il newfoo, dal momento che foo è un vector, non un puntatore ad un vector (vale a dire std::vector<my_obj*> *foo).

Se si proviene da Java o C#, è possibile prendere in considerazione l'utilizzo di std::vector<my_obj> (un vettore di oggetti) anziché un vettore di puntatori. Dipende davvero da cosa vuoi fare.

3

Perché foo è un un puntatore non oggetto.

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

Nuova rerturns un puntatore:

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

PS. Probabilmente il vettore dovrebbe contenere oggetti e non puntatori.

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

altrimenti sarà necessario eliminare manualmente tutti gli oggetti nel vettore quando passa nell'ambito (qualora l'oggetto contenente viene distrutto). Ad esempio, se vuoi mantenere i puntatori nel tuo vettore, devi eseguire una delle seguenti azioni:

// 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 
Problemi correlati