Sotto molti aspetti std::unique_ptr
è stato realizzato per essere sostituito (ma più sicuro) per std::auto_ptr
, quindi ci dovrebbero essere pochissime (se ce ne sono) modifiche al codice richieste diverse da (come chiedi) indirizzando il codice per utilizzare unique_ptr
o auto_ptr
.
Ci sono alcuni modi per farlo (e ognuno ha i propri compromessi con le liste) di seguito. Dato il codice di esempio fornito, preferirei una delle due prime opzioni .
Opzione 1
#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
Compromessi;
- Si introduce il nome
auto_ptr
nello spazio dei nomi globale; puoi mitigarlo definendo che è il tuo spazio dei nomi "privato"
- Una volta migrata in C ++ 17 (credo che
auto_ptr
sarà completamente rimossa) puoi più facilmente cercare e sostituire
Opzione 2
template <typename T>
struct my_ptr {
#if __cplusplus >= 201103L
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
Compromessi;
- Probabilmente più ingombrante con cui lavorare, tutti gli
auto_ptr
attuali devono essere cambiati nel codice in qualcosa come my_ptr<T>::ptr
- Maggiore sicurezza i nomi non vengono introdotti nello spazio dei nomi globale
Opzione 3
Piuttosto controverso, ma se sei pronto a sopportare le avvertenze di avere una classe std
come base
#if __cplusplus >= 201103L
template <typename T>
using my_ptr = std::unique_ptr<T>;
#else
template <typename T>
class my_ptr : public std::auto_ptr<T> {
// implement the constructors for easier use
// in particular
explicit my_ptr( X* p = 0 ) : std::auto_ptr(p) {}
};
#endif
Compromessi;
- Non tentare di utilizzare la classe ereditata dove ci si aspetterebbe una base virtuale (in particolare il distruttore non virtuale w.r.t. Non che questo dovrebbe essere un problema nel caso, ma sii consapevole di ciò
- Anche in questo caso, le modifiche al codice
- Scomparamenti di spazio dei nomi potenziali - tutto dipende da come viene utilizzata la classe pointer per iniziare con
Opzione 4
Avvolgi i puntatori in una nuova classe e aggrega le funzioni richieste al membro
template <typename T>
class my_ptr { // could even use auto_ptr name?
#if __cplusplus >= 201103L
std::unique_ptr<T> ptr_;
#else
std::auto_ptr<T> ptr_;
#endif
// implement functions required...
T* release() { return ptr_.release(); }
};
Compromessi;
- Un po 'estremo quando tutto ciò che vuoi veramente è "scambiare" le implementazioni