Я пытаюсь создать функцию, которая принимает auto_ptr
в Base
класс, и я хотел бы назвать это с auto_ptr
в Derived
учебный класс. Однако я не могу сделать это.
Я пытался использовать его без ссылки:
void function(std::auto_ptr<Base> ptr);
std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); // error: #348: more than one user-defined conversion from
// "std::auto_ptr<Derived>" to "std::auto_ptr<Base>" applies
И со ссылкой:
void function(std::auto_ptr<Base>& ptr);
std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); //error: #304: no instance of overloaded function "function"// matches the argument list
РЕДАКТИРОВАТЬ:
Я знаю, что auto_ptr устарела, но у меня есть доступ только к C++03
и не могу получить доступ boost
, Поэтому я был бы признателен, если бы ответы были сосредоточены на самом вопросе 🙂 Я также понимаю разницу между функцией, принимающей ссылку и auto_ptr по значению. В моем фактическом коде функция становится владельцем auto_ptr
так что оба хорошо, если я могу получить преобразование из Derived
в Base
за работой.
Вы можете сыграть без двусмысленности:
function(static_cast<std::auto_ptr<Base> >(derivedPtr));
Помните, что для этого нужно работать, Base
должен иметь виртуальный деструктор. В противном случае код имеет неопределенное поведение.
Причина двусмысленности в том, что Арне говорит в своем ответе — для звонящего не очевидно, function
принимает значение или ссылку, и поэтому для вызывающего абонента не очевидно, auto_ptr
будет выпущен или нет при выполнении вызова, и если он будет выпущен, будет ли он преобразован в тип, который может правильно delete
указатель Неоднозначное преобразование AFAIK поможет вам написать такой сложный код. Делая это, вы делаете это явно в вызывающем коде, который derivedPtr
выпущен.
Вы пытаетесь auto_ptr
по значению и по ссылке, которые совершенно разные вещи. Вызов по значению означает, что вы передаете право собственности на функцию, так как auto_ptr
делает это на копии. Звоните по ссылке значит есть только auto_ptr
вне функции, которая сохраняет право собственности.
Так как это различие очень неинтуитивно, auto_ptr
устарел в стандарте 2011 года, и авторы препятствуют использованию auto_ptr
намного длиннее. Короче:
Не использовать auto_ptr
совсем.
Использовать unique_ptr
если вы хотите передать владение в функцию, или ссылку или простой указатель, если вы хотите оставить его вне функции. Это зависит от конкретного случая, который у вас есть.
Обновить: так как вы упоминаете, что вы должны использовать C ++ 03 без наддува, для C ++ 03 существует реализация unique_ptr: http://howardhinnant.github.io/unique_ptr03.html
Он использует несколько функций буста, которые можно легко написать от руки, поэтому его можно перенести на платформу без использования буста.
Лучше управлять памятью вручную, чем использовать auto_ptr
как его использование так чревато ошибками.
Лучше всего использовать замену промышленной силы: в худшем случае, изучите либеральную boost
изучите и определите, можете ли вы написать свой собственный клон.
Failimg что, напишите свою собственную замену owning_ptr
, Создать ownomg_ptr_transfer
учебный класс template
также. Блочное копирование конструкции на owning_ptr
, бит включить неявное преобразование из owning_ptr_transfer
который принимает основной указатель. Имейте свободную функцию или метод, который перемещает основной указатель на объект передачи.
По сути, если нужно, напишите свой unique_ptr
используя C ++ 03.
Если вы не будете использовать чужое решение и не будете писать свое собственное, просто запишите память вручную. auto_ptr
это того не стоит: это не просто неоптимальный по сравнению с unique_ptr
На самом деле это вредно: его цель — упростить управление памятью, а вместо этого сделать его более подверженным ошибкам. Это был эксперимент, и он не удался.