DOMANDA C++ quando usare static_cast<> rispetto al Regular Cast

Pubblicità

peterpaolo94

Utente Attivo
Messaggi
254
Reazioni
22
Punteggio
38
Salve ragazzi, è un po di tempo oramai che non rientro sul forum per vari motivi, oggi però mi è venuto un dubbio riguardante la programmazione ed ho pensato di chiedere a voi delucidazioni.
Come da titolo, quando conviene usare lo static_cast<> rispetto ad regular cast?
ovviamente ho già cercato a dovere su Internet e molti miei dubbi sono svaniti, infatti ho capito che lo static_cast<> è un po più restrittivo del cast classico e permette una verifica a tempo di compilazione mentre il cast potrebbe risultare in errori a tempo di esecuzione (proprio perchè non fa controlli ne a tempo di compilazione ne in esecuzione).
Sono quindi giunto alla mia prima conclusione, ovvero che se sono sicuro di passare i giusti tipi ai cast, e sono sicuro che questi non daranno errori di conversione, allora posso tranquillamente usare il regular cast, giusto?
passiamo ora all'esempio:
C++:
struct esempio {
    /*
    ... Cose ...
    */
};

// cast regolare
esempio *ex = (esempio *)(mem_alloc(sizeof(esempio)));

//static_cast
esempio *ex = static_cast<esempio*>(mem_alloc(sizeof(esempio)));

perchè in questo esempio dovrei usare lo static cast rispetto al regular cast?
La mem_alloc restituisce un puntatore a void: void * mem_alloc(dim)
 
Sono quindi giunto alla mia prima conclusione, ovvero che se sono sicuro di passare i giusti tipi ai cast, e sono sicuro che questi non daranno errori di conversione, allora posso tranquillamente

La frase sopra il motivo principale per cui dovresti usare soltanto C++ style cast.
Se usi le parole "sicuro" e "tranquillamente" parlando di cast, sono 200% sicuro che prima o poi finirai per scrivere qualche brutto bug :D

Questo video a partire da 6:38 ne parla approfonditamente in ordine, lasciando il C style cast per ultimo e da alcune buone motivazione per evitarlo, tra le quali è davvero difficile da cercare, mentre invece ci vuole un attimo per trovare tutti gli static_cast nel tuo codice :)
Cmq no, nel tuo esempio sopra non dovresti avere problemi, però tieni a mente tutti gli altri casi che sono la stragrande maggioranza.
 
Ultima modifica:
bhe se non hai problemi con i puntatori normali, non dovresti averne manco con gli smart pointers, ecco un esempio:
C++:
unique_ptr<D2DWindow> window;
window = make_unique<D2DWindow>(clientWidth, clientHeight);
o in una sola linea:
C++:
auto window = make_unique<D2DWindow>(clientWidth, clientHeight);

e tra le parentesi passi gli stessi argomenti che avresti passato al costruttore della classe.
E non devi ricordarti di chiamare delete, l'unique_ptr si occupa di tutto lui, attualmente mi infastidisce anche solo il pensiero di dovere usare un "new" e dovermi ricordare di usare "delete"...sarà che son pigro io xD
 
bhe se non hai problemi con i puntatori normali, non dovresti averne manco con gli smart pointers, ecco un esempio:
C++:
unique_ptr<D2DWindow> window;
window = make_unique<D2DWindow>(clientWidth, clientHeight);
o in una sola linea:
C++:
auto window = make_unique<D2DWindow>(clientWidth, clientHeight);

e tra le parentesi passi gli stessi argomenti che avresti passato al costruttore della classe.
E non devi ricordarti di chiamare delete, l'unique_ptr si occupa di tutto lui, attualmente mi infastidisce anche solo il pensiero di dovere usare un "new" e dovermi ricordare di usare "delete"...sarà che son pigro io xD
Praticamente è una classe template che ha gli operatori [ ], ->, &, ... sovraccaricati e il costruttore ha come parametro un puntatore (che proviene poi dalla memoria dinamica) e ha il distruttore che invoca il delete?
Ah sì già che ci sono auto è una variabile generica? Perché l’ho vista usata anche per <chrono>
 
Bhe non sono la persona piu adatta per rispondere su cosa sia un unique_ptr, posso solo dirti che ci sono valide ragioni di sicurezza per preferire make_unique<tuaClasse> a new tuaClasse quando inizializzi un unique_ptr.
In maniera simmetrica,
shared_ptr usa make_shared<tuaClasse>

Questa è la definizione della classe:
template<class T, class Deleter = std::default_delete<T>>
T rappresenta il tipo che passi tu, nel mio esempio sopra era D2DWindow mentre invece Deleter rappresenta una funzione che tu puoi passare e che in pratica è quello che succede quando il distruttore dell'unique_ptr viene chiamato, ed il = std::default_delete<T> significa che se tu non fornisci un deleter (come nel mio caso sopra) semplicemente viene chiamato delete sul raw pointer gestito dall'unique_ptr.
Ma se come nel caso dei pointer ritornati dalle funzioni in Direct3D che quando li rilasci devi fare pointer->Release(); , in quel caso allora devi fornire all'unique_ptr un deleter che appunto fà quello.

auto deduce il tipo per te, nell'esempio
C++:
auto window = make_unique<D2DWindow>(clientWidth, clientHeight);
il compiler sà benissimo che make_unique sta ritornando un
unique_ptr<D2DWindow> percui auto viene dedotto come unique_ptr<D2DWindow> .
auto in sostanza lascia che sia il compiler a scegliere il giusto tipo per te. Cmq mi sa che siamo offtopic xD
 
Pubblicità
Pubblicità
Indietro
Top