C ++ - Есть ли здесь неявное приведение от Fred * к auto_ptr <Fred>? - PullRequest
4 голосов
/ 02 января 2011

Я видел следующий код,

#include <new>
#include <memory>
using namespace std;

class Fred;  // Forward declaration
typedef  auto_ptr<Fred>  FredPtr;

class Fred {
public:
  static FredPtr create(int i)
  { 
    return new Fred(i); // Is there an implicit casting here? If not, how can we return
                        // a Fred* with return value as FredPtr?
  }
private:
  Fred(int i=10)      : i_(i)    { }
  Fred(const Fred& x) : i_(x.i_) { }
  int i_;
};

Пожалуйста, посмотрите вопрос, указанный в функции create.

Спасибо

// Обновлено на основе комментариев

Да, код не может передать ошибку VC8.0 C2664: 'std :: auto_ptr <_Ty> :: auto_ptr (std :: auto_ptr <_Ty> &) throw ()': невозможно преобразовать параметр 1 из 'Fred *'to' std :: auto_ptr <_Ty> & '

Код был скопирован из C ++ FAQ 12.15.

Однако, после внесения следующих изменений,

replace 
  return new Fred(i);
with
  return auto_ptr<Fred>(new Fred(i));

Этот код может пройти компилятор VC8.0.Но я не уверен, является ли это правильным исправлением.

Ответы [ 3 ]

6 голосов
/ 02 января 2011

std::auto_ptr имеет конструктор, который принимает необработанный указатель в качестве аргумента, но этот конструктор имеет значение explicit и не может использоваться как конструктор преобразования.

Этот код не будет компилироваться.

3 голосов
/ 02 января 2011

Нет, такого неявного преобразования не существует.Оказывается, это действительно хорошая вещь, хотя.Например, рассмотрим следующий код:

void MyFunction(const std::auto_ptr<Fred>& myFred) {
   /* ... do something to Fred. */
}

int main() {
    Fred* f = new Fred;
    MyFunction(f); // Not legal, but assume it is.
    f->doSomething();
}

Здесь, если вы можете передать необработанный указатель на Fred в MyFunction, то когда эта функция вернется и временный объект auto_ptr будет очищен, память, выделенная вами вmain () будет исправлено, и вызов f-> doSomething (), вероятно, вызовет ошибку segfault.Создание явного конструктора auto_ptr является гарантией против этого;Вы не хотите случайно приобрести эксклюзивное право собственности на ресурс, если кто-то еще считает, что у него уже есть такой доступ.

0 голосов
/ 02 января 2011

Фиксированная версия кода (return std::auto_ptr<Fred>(new Fred())) является правильной и действительной C ++.Тем не менее, я не уверен, что функция create() покупает в том, что создание std::auto_ptr<T> должно быть в наборе навыков любого программиста C ++.Точно так же я не совсем понимаю, что покупает typedef ing std::auto_ptr<Fred> до FredPtr, кроме необходимости выяснить, что на самом деле является FredPtr

...