как работает эта программа auto_ptr и что она делает? - PullRequest
2 голосов
/ 27 мая 2011

Я запустил эту программу, но я не понял, что делает этот auto_ptr и на каких основах он показывает значения?

int main(int argc,char **argv)
{
    int *i= new int;
    auto_ptr<int> x(i);
    auto_ptr<int>y;
    y=x;
    count <<x.get()<<endl;
    count <<y.get()<<endl;
}

Ответы [ 6 ]

8 голосов
/ 27 мая 2011

Этот код будет печатать адрес NULL для первого объекта auto_ptr и некоторый не-NULL адрес для второго, показывая, что исходный объект потерял ссылку во время присваивания (=).

1 голос
/ 27 мая 2011

Для этой программы auto_ptr похож на обычный указатель, за исключением:

  • это delete любой объект, который все еще заострен, когда он выходит из области видимости
  • если вы копируете из одного объекта auto_ptr в другой, скопированный объект «забудет» об отслеживаемом объекте

Итак, x изначально принимает значение i. Затем y=x фактически просит x забыть о i (сохраняя вместо этого значение часового значения NULL), а y запомнить i. Затем при печати значений указателя, возвращаемых get, будет показано значение NULL / 0 для x и значение, отличное от NULL (соответствует i) для y. Затем, когда main() возвращает, y и x покидают область видимости, а поскольку y содержит значение указателя, отличное от NULL, совпадающее с i, оно delete будет содержать объект int, освобождая память кучи.

1 голос
/ 27 мая 2011

auto_ptr предполагает владение указателем, с помощью которого вы его строите.

т.е.он будет автоматически уничтожать объект, на который указывает указанный объект, как только сам auto_ptr будет уничтожен.

auto_ptr<int> x(i) сделает x владельцем i

auto_ptr<int> y сделает вас не владеющим ничем

Ваша y=x операция переведет владение i * из x в y

, так что теперь y владеет i, а x ничего не имеет, это означает, что когда x уничтожается, ничего не происходит, а когда y уничтожается, i удаляется

1 голос
/ 27 мая 2011

В двух словах, auto_ptr - это шаблонный объект, и когда его переменная выходит из области видимости, вызывается деструктор, который освобождает приобретенную им память. Это одна из самых простых версий умных указателей.

1 голос
/ 27 мая 2011

auto_ptr автоматически освобождает память, выделенную new в конце своей области (в этом случае, когда основной выход). Однако этот пример довольно глуп, потому что целое число никогда не получает фактическое значение, поэтому я должен представить, что вы видите мусор.

Это может быть немного более показательным:

int main(int argc,char **argv)
{
    int *i= new int;
    *i = 5;
    auto_ptr<int> x(i);
    auto_ptr<int>y;

    y=x;

    count << *(x.get()) <<endl;
    count << *(y.get()) <<endl;

    *x.get() = 7;

    count << *(x.get()) <<endl;
    count << *(y.get()) <<endl;
}
0 голосов
/ 27 мая 2011

auto_ptr вступает во владение объектом. Важно отметить, что

  • Будет удален внутренний объект
  • Копирование / назначение auto_ptrs передает право собственности
  • Будет устаревшим в c ++ 0x и заменен на unique_ptr

По этим причинам он, как правило, используется в сочетании с парадигмой RAII (Resource Acquisition is Initializtion). Например, допустим, что вы выделили переменную, не сохраняя ее в auto_ptr, тогда вам придется самостоятельно управлять удалением памяти. Приведенный ниже пример показывает, что это нужно сделать дважды: один раз для хорошего пути и один раз для неудачного пути.

A* p(new A);
try {
    ....
}
catch (std::exception& e) {
   delete p;
   return;
}
delete p;

Если вместо этого мы использовали auto_ptr, это избавит нас от необходимости помнить об удалении выделенной памяти.

auto_ptr<A> p(new A);
try {
    ....
}
catch (std::exception& e) {
    ....
}
...