PDA

Visualizza la versione completa : [C++] Return di un vector privato


Eyescream
28-11-2009, 11:25
Ciao,
ho nella parte privata di una classe un vector a cui aggiungo elementi dall'interno della classe.
Avrei la necessità di ritornare questo vector per utilizzarlo (anche) al di fuori della classe stessa.
esempio:

class vet{
private:
vector <string> st;
public:
vet(){
st.push_back("uno");
st.push_back("due");
}

vector <string> getSt(){
return st;
}
};
Il metodo getSt provoca una copia del vector, che al momento non è un grosso problema, ma potrebbe diventarlo nel caso in cui st diventasse molto grande.

Allora ho pensato di scrivere un metodo del genere:


const vector <string>* getSt_nocopy(){
return &st;
}
E' sensato? Oppure va assolutamente contro l'information hiding/buona oop?
Di fatto è costante per cui danni non se ne potrebbero fare da fuori.

Grazie 1k

XWolverineX
28-11-2009, 11:29
Se ne ritorni una nuova copia non vedo problemi di "integrità" della classe.
Ritornare un riferimento sarebbe ben piu' pericosolo.

Information hiding...veramente non vedo nemmeno nessuna violazione, in quanto l'oggetto potrebbe essere un "produttore" di vector<string> e sfornare il prodotto finito.

Eyescream
28-11-2009, 11:46
Integrità ok, però io parlavo di prestazioni.


Ritornare un riferimento sarebbe ben piu' pericosolo.per quello lo ritorno const.. non vedo altri modi per evitare una copia comunque.


Information hiding...veramente non vedo nemmeno nessuna violazioneIl termine information hiding forse è scorretto, intendevo dire che forse semplicemente non è buona programmazione ad oggetti ed è una cosa che va evitata in qualsiasi caso.

MItaly
28-11-2009, 12:24
Io restituirei un riferimento const. Se al chiamante serve farsene una copia per smanettarci su può farlo senza problemi, mentre ai chiamanti a cui serve solo dare un'occhiata agli elementi non si impone l'overhead della copia. L'unico dubbio che mi viene è se gli elementi possano essere comunque modificati.

shodan
28-11-2009, 12:38
Originariamente inviato da Eyescream
Allora ho pensato di scrivere un metodo del genere:


const vector <string>* getSt_nocopy(){
return &st;
}
E' sensato? Oppure va assolutamente contro l'information hiding/buona oop?
Di fatto è costante per cui danni non se ne potrebbero fare da fuori.




const vector <string>* p = vett.getSt_nocopy();
delete p;

e tanti saluti al vector interno.

Io ho fatto così in un caso simile.


class vet{
private:
vector <string> st;
public:
vet(){
st.push_back("uno");
st.push_back("due");
}

vector <string>::iterator begin() {
return st.begin();
}

vector <string>::iterator end() {
return st.end();
}
};

Non esponi il vector interno, accedi agli elementi interni senza problemi e lo copi solo se ti serve.

Eyescream
28-11-2009, 13:13
const vector <string>* p = vett.getSt_nocopy();
delete p;

questo non penso compili [edit provato, non compila] in quanto è const,
l'idea degli iterators è buona, mi sembra un po meno brutale del riferimento costante

KrOW
28-11-2009, 13:44
Ciao . . . Io definirei dei metodi che non fanno altro che richiamare i "corrispondenti" di vector ( ovviamenti solo quelli utili ) :

class vet
{
vetor< string > st;
public:
int getSize( ) const { return st.size(); }
const string& operator[] ( int index ) const { return st[ index ]; }
// altri metodi . . .
};

shodan
28-11-2009, 14:20
Originariamente inviato da Eyescream


const vector <string>* p = vett.getSt_nocopy();
delete p;

questo non penso compili [edit provato, non compila] in quanto è const,

A me invece compila benissimo. (VC++ Express)

Il fatto che un puntatore sia const non impedisce alla delete di funzionare.

http://www.eptacom.net/pubblicazioni/pub_it/iso_3.html

Eyescream
28-11-2009, 14:58
che pessimo! mi cade una certezza :D a me dava
passing `const std::vector<std::string, std::allocator<std::string> >' as `this' argument of `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::string, _Alloc = std::allocator<std::string>]' discards qualifiers|

MItaly
28-11-2009, 19:40
Originariamente inviato da shodan
Il fatto che un puntatore sia const non impedisce alla delete di funzionare.

http://www.eptacom.net/pubblicazioni/pub_it/iso_3.html
Che idiozia... credo che le occasioni in cui è necessario rilasciare la memoria puntata da un puntatore const siano molte meno rispetto a quelle in cui sarebbe comodo che ciò fosse proibito. Se è proprio necessario in quelle rare occasioni si potrebbe usare un const_cast...

In ogni caso, come detto, credo che la cosa migliore sia restituire un const vector<string> &; ciò blocca ogni tentativo di modificare il vector nonché gli elementi, e per effettuare una delete bisogna che il chiamante vada a cercarsi il puntatore apposta (con l'operatore &), il che è assolutamente controintuitivo.

Loading