Ciao.
Ho letto che è una buona pratica in c++ (stl) utilizzare il typedef e ho capito la sitassi e l'uso na non quali sono i vantaggi!
Ciao.
Ho letto che è una buona pratica in c++ (stl) utilizzare il typedef e ho capito la sitassi e l'uso na non quali sono i vantaggi!
In linea generale, il typedef serve per astrarre il tipo di dato in modo da poterlo usare senza sapere cosa esso sia.
Supponi di creare una classe che faccia uso pesantemente di un container, ad esempio vector<int>. Inizi ad usarlo un pò dappertutto nella classe, poi ad un certo momento ti accorgi che per ragioni di perfomance o altro è meglio usare una deque<int> o una list<int>.
I casi sono due: o ti rileggi tutto il codice e cambi manuamente il container, oppure all'inizio scrivi.
E usi il nuovo alias come nome di variabile, senza cambiare in seguito una singola linea di codice.codice:typedef std::vector<int> Contenitore; // typedef std::deque<int> Contenitore; // typedef std::list<int> Contenitore;
Se ti serve un container diverso, basta commentare la prima linea e decommentare una delle seguenti.
Serve anche per abbreviare le definizioni.
Da tuo codice:
codice:typedef CArray<int, int> CArr_int; bool CSapBase::ImportSelectionGroup(CString* strGroup, CArr_int* pArrJoint, CArr_int* pArrBeam, CArr_int* pArrShell) ...etc..
This code and information is provided "as is" without warranty of any kind, either expressed
or implied, including but not limited to the implied warranties of merchantability and/or
fitness for a particular purpose.
Confermo ciò che ti ha detto shodan: in particolare nel mio codice uso proprio Container che di volta in volta sono list, vector ecc..
Servono anche per rendere più leggibili certe dichiarazioni, ad esempio:
come vedi la prima senza typedef è praticamente illeggibilecodice:$ man signal ... void (*signal(int sig, void (*func)(int)))(int); or in the equivalent but easier to read typedef'd version: typedef void (*sig_t) (int); sig_t signal(int sig, sig_t func); ...
;-)
in parole molto semplici, il typedef (come dice la parola stessa) ti consente di creare una nuova tiopologia di dato che è diversa da quelle standard di base che ci sono in c++.
in questo modo, puoi dichiarare e utilizzare variabili o oggetti del tipo da te dichiarato che può essere qualsiasi. Questa possibilità di definire nuovi tipi sembra assurda, ma è molto utile!
Oltre alla comodità di cambiare contenitore, spesso con la STL se non usi typedef puoi arrivare ad avere dichiarazioni mostruose; con i typedef:
Senza typedef:codice:class INISection { //Typedef for the internal map typedef std::map<std::_tcstring,std::_tcstring,CaseInsensitive_Less> ISmap; /* ... */ } /* ... */ void MeasurementUnitsContainer::RemoveDataFromINI(INISection & IniSect) { IniSect.Read(); typedef std::list<INISection::ISmap::iterator> itList; itList toDelete; INISection::ISmap & im=IniSect.GetInternalMap(); { std::_tcstring prefix(_T("MUItem")); INISection::ISmap::iterator it, end=im.end(); for(it=im.begin();it!=end;it++) { if(it->first.compare(0,prefix.size(),prefix)==0) toDelete.push_back(it); } } { itList::const_iterator it, end=toDelete.end(); for(it=toDelete.begin();it!=end;it++) im.erase(*it); } IniSect.Write(); }
Immagina poi senza typedef che gioia se dovessi cambiare il tipo di INISection::ISMap...codice:void MeasurementUnitsContainer::RemoveDataFromINI(INISection & IniSect) { IniSect.Read(); std::list< std::map<std::_tcstring,std::_tcstring,CaseInsensitive_Less>::iterator > toDelete; std::map<std::_tcstring,std::_tcstring,CaseInsensitive_Less> & im=IniSect.GetInternalMap(); { std::_tcstring prefix(_T("MUItem")); std::map<std::_tcstring,std::_tcstring,CaseInsensitive_Less>::iterator it, end=im.end(); for(it=im.begin();it!=end;it++) { if(it->first.compare(0,prefix.size(),prefix)==0) toDelete.push_back(it); } } { std::list< std::map<std::_tcstring,std::_tcstring,CaseInsensitive_Less>::iterator >::const_iterator it, end=toDelete.end(); for(it=toDelete.begin();it!=end;it++) im.erase(*it); } IniSect.Write(); }![]()
Amaro C++, il gusto pieno dell'undefined behavior.