Читаем C++ Primer Plus полностью

That causes films[2] to no longer refer to the string. After an auto_ptr gives up ownership of an object, it no longer provides access to the object. When the program goes to print the string pointed to by films[2], it finds the null pointer, which apparently is an unpleasant surprise.

Suppose you go back to Listing 16.6 but use shared_ptr instead of auto_ptr. (You’ll need a compiler that supports the C++11 shared_ptr class.) Then the program runs fine and gives this output:

The nominees for best avian baseball film are

Fowl Balls

Duck Walks

Chicken Runs

Turkey Errors

Goose Eggs

The winner is Chicken Runs!

The difference occurs in this part of the program:

shared_ptr pwin;

pwin = films[2];

This time both pwin and films[2] point to the same object, and the reference count is upped from 1 to 2. At the end of the program, pwin, which was declared last, is the first object to have its destructor called. The destructor decreases the reference count to 1. Then the members of the array of shared_ptrs are freed. The destructor for films[2] decrements the count to 0 and frees the previously allocated space.

So with shared_ptr, Listing 16.6 runs fine. With auto_ptr it experienced a runtime crash. What happens if you use unique_ptr? Like auto-ptr, unique_ptr incorporates the ownership model. Yet instead of crashing, the unique_ptr version yields a compile-time error objecting to this line:

pwin = films[2];

Clearly, it is time to look further into the differences between these last two types.

Why unique_ptr Is Better than auto_ptr

Consider the following statements:

auto_ptr p1(new string("auto");  //#1

auto_ptr p2;                     //#2

p2 = p1;                                 //#3

When, in statement #3, p2 takes over ownership of the string object, p1 is stripped of ownership. This, recall, is good because it prevents the destructors for both p1 and p2 from trying to delete the same object. But it also is bad if the program subsequently tries to use p1 because p1 no longer points to valid data.

Now consider the unique_ptr equivalent:

unique_ptr p3(new string("auto");  //#4

unique_ptr p4;                     //#5

p4 = p3;                                   //#6

In this case, the compiler does not allow statement #6, so we avoid the problem of p3 not pointing to valid data. Hence, unique_ptr is safer (compile-time error versus potential program crash) than auto_ptr.

But there are times when assigning one smart pointer to another doesn’t leave a dangerous orphan behind. Suppose we have this function definition:

unique_ptr demo(const char * s)

{

    unique_ptr temp(new string(s));

    return temp;

}

And suppose we then have this code:

unique_ptr ps;

ps = demo("Uniquely special");

Here, demo() returns a temporary unique_ptr, and then ps takes over ownership of the object originally owned by the returned unique_ptr. Then the returned unique_ptr is destroyed. That’s okay because ps now has ownership of the string object. But another good thing has happened. Because the temporary unique_ptr returned by demo() is soon destroyed, there’s no possibility of it being misused in an attempt to access invalid data. In other words, there is no reason to forbid assignment in this case. And, miraculously enough, the compiler does allow it!

In short, if a program attempts to assign one unique_ptr to another, the compiler allows it if the source object is a temporary rvalue and disallows it if the source object has some duration:

using namespace std;

unique_ptr< string> pu1(new string "Hi ho!");

unique_ptr< string> pu2;

pu2 = pu1;                                   //#1 not allowed

unique_ptr pu3;

pu3 = unique_ptr(new string "Yo!");  //#2 allowed

Assignment #1 would leave a dangling unique_ptr behind (that is, pu1), a possible source of mischief. Assignment #2 leaves no unique_ptr behind because it invokes the unique_ptr constructor, which constructs a temporary object that is destroyed when ownership is transferred to pu3. This selective behavior is one indication that unique_ptr is superior to auto_ptr, which would allow both forms of assignment. It’s also the reason that auto_ptrs are banned (by recommendation, not by the compiler) from being used in container objects, whereas unique_ptrs are allowed. If a container algorithm tries to do something along the lines of assignment #1 to the contents of a container of unique_ptrs, you get a compile-time error. If the algorithm tries to do something like assignment #2, that’s okay, and the program proceeds. With auto_ptrs, cases like assignment #1 could lead to undefined behavior and mysterious crashes.

Перейти на страницу:

Все книги серии Developer's Library

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных