У більшості аспектів це std::unique_ptr
було зроблено для заміни (але більш безпечної) заміни std::auto_ptr
, тому повинно бути дуже мало (якщо є) змін коду, необхідних, крім (як ви запитуєте) спрямування коду на використання unique_ptr
або auto_ptr
.
Нижче є декілька способів зробити це (і кожен має свій власний список). Враховуючи зразок коду, що надається, я віддаю перевагу одному з перших двох варіантів .
Варіант 1
#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
Компроміси;
- Ви вводите
auto_ptr
ім'я в глобальний простір імен; ви можете пом'якшити це, визначивши це власний "приватний" простір імен
- Після переходу на C ++ 17 (я вважаю,
auto_ptr
буде повністю видалено), ви можете легше шукати та замінювати
Варіант 2
template <typename T>
struct my_ptr {
#if __cplusplus >= 201103L
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
Компроміси;
- Напевно, більш громіздко працювати, всю поточну
auto_ptr
потребу в коді змінити на щось подібнеmy_ptr<T>::ptr
- Краща безпека імен не вводиться в глобальний простір імен
Варіант 3
Дещо суперечливий, але якщо ви готові миритися з застереженнями про те, що std
клас є базовим
#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
Компроміси;
- Не намагайтеся використовувати успадкований клас там, де очікується віртуальна база (зокрема wrt невіртуальний деструктор). Мало того, що це має бути проблемою у справі - але пам’ятайте про це
- Знову ж, зміни коду
- Невідповідність потенційних просторів імен - все залежить від того, з чого використовується клас вказівника для початку
Варіант 4
Оберніть покажчики в новий клас і зберіть необхідні функції для члена
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(); }
};
Компроміси;
- Трохи крайність, коли все, що ти справді хочеш, - це "поміняти місцями" реалізації
auto_ptr
областей дії (тобтоstd::auto_ptr
), чи вони повинні бути, чи інтелектуальний вказівник можна отримати з якогось іншого простору імен?