Scott Meyers - Effective Modern C++

Здесь есть возможность читать онлайн «Scott Meyers - Effective Modern C++» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Sebastopol, Год выпуска: 2014, ISBN: 2014, Издательство: O’Reilly, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Effective Modern C++: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Effective Modern C++»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Coming to grips with C++11 and C++14 is more than a matter of familiarizing yourself with the features they introduce (e.g., auto type declarations, move semantics, lambda expressions, and concurrency support). The challenge is learning to use those features
— so that your software is correct, efficient, maintainable, and portable. That's where this practical book comes in. It describes how to write truly great software using C++11 and C++14 — i.e., using
C++.
Topics include:
■ The pros and cons of braced initialization,
specifications, perfect forwarding, and smart pointer make functions
■ The relationships among
,
, rvalue references, and universal references
■ Techniques for writing clear, correct,
lambda expressions
■ How
differs from
, how each should be used, and how they relate to C++'s concurrency API
■ How best practices in “old” C++ programming (i.e., C++98) require revision for software development in modern C++
Effective Modern C++ For more than 20 years,
'
books (
,
, and
) have set the bar for C++ programming guidance. His clear, engaging explanations of complex technical material have earned him a worldwide following, keeping him in demand as a trainer, consultant, and conference presenter. He has a Ph.D. in Computer Science from Brown University.
“After I learned the C++ basics, I then learned how to use C++ in production code from Meyers' series of Effective C++ books. Effective Modern C++ is the most important how-to book for advice on key guidelines, styles, and idioms to use modern C++ effectively and well. Don't own it yet? Buy this one. Now.”
Herb Sutter
Chair of ISO C++ Standards Committee and C++ Software Architect at Microsoft

Effective Modern C++ — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Effective Modern C++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

You may be wondering how a std::weak_ptrcould be useful. You'll probably wonder even more when you examine the std::weak_ptrAPI. It looks anything but smart. std::weak_ptrs can't be dereferenced, nor can they be tested for nullness. That's because std::weak_ptrisn't a standalone smart pointer. It's an augmentation of std::shared_ptr.

The relationship begins at birth. std::weak_ptrs are typically created from std::shared_ptrs. They point to the same place as the std::shared_ptrs initializing them, but they don't affect the reference count of the object they point to:

auto spw = // after spw is constructed,

std::make_shared(); // the pointed-to Widget's

// ref count (RC) is 1. (See

// Item 21 for info on

// std::make_shared.)

std::weak_ptrwpw(spw); // wpw points to same Widget

// as spw. RC remains 1

spw = nullptr; // RC goes to 0, and the

// Widget is destroyed.

// wpw now dangles

std::weak_ptrs that dangle are said to have expired . You can test for this directly,

if ( wpw.expired()) … // if wpw doesn't point

// to an object.

but often what you desire is a check to see if a std::weak_ptrhas expired and, if it hasn't (i.e., if it's not dangling), to access the object it points to. This is easier desired than done. Because std::weak_ptrs lack dereferencing operations, there's no way to write the code. Even if there were, separating the check and the dereference would introduce a race condition: between the call to expiredand the dereferencing action, another thread might reassign or destroy the last std::shared_ptrpointing to the object, thus causing that object to be destroyed. In that case, your dereference would yield undefined behavior.

What you need is an atomic operation that checks to see if the std::weak_ptrhas expired and, if not, gives you access to the object it points to. This is done by creating a std::shared_ptrfrom the std::weak_ptr. The operation comes in two forms, depending on what you'd like to have happen if the std::weak_ptrhas expired when you try to create a std::shared_ptrfrom it. One form is std::weak_ptr::lock, which returns a std::shared_ptr. The std::shared_ptris null if the std::weak_ptrhas expired:

std::shared_ptr spw1 = wpw. lock(); // if wpw's expired,

// spw1 is null

auto spw2 = wpw. lock(); // same as above,

// but uses auto

The other form is the std::shared_ptrconstructor taking a std::weak_ptras an argument. In this case, if the std::weak_ptrhas expired, an exception is thrown:

std::shared_ptrspw3(wpw); // if wpw's expired,

// throw std::bad_weak_ptr

But you're probably still wondering about how std::weak_ptrs can be useful. Consider a factory function that produces smart pointers to read-only objects based on a unique ID. In accord with Item 18's advice regarding factory function return types, it returns a std::unique_ptr:

std::unique_ptr loadWidget(WidgetID id);

If loadWidgetis an expensive call (e.g., because it performs file or database I/O) and it's common for IDs to be used repeatedly, a reasonable optimization would be to write a function that does what loadWidgetdoes, but also caches its results. Clogging the cache with every Widgetthat has ever been requested can lead to performance problems of its own, however, so another reasonable optimization would be to destroy cached Widgets when they're no longer in use.

For this caching factory function, a std::unique_ptrreturn type is not a good fit. Callers should certainly receive smart pointers to cached objects, and callers should certainly determine the lifetime of those objects, but the cache needs a pointer to the objects, too. The cache's pointers need to be able to detect when they dangle, because when factory clients are finished using an object returned by the factory, that object will be destroyed, and the corresponding cache entry will dangle. The cached pointers should therefore be std::weak_ptrs — pointers that can detect when they dangle. That means that the factory's return type should be a std::shared_ptr, because s td::weak_ptrs can detect when they dangle only when an object's lifetime is managed by std::shared_ptrs.

Here's a quick-and-dirty implementation of a caching version of loadWidget:

std::shared_ptr fastLoadWidget(WidgetID id) {

static std::unordered_map

std::weak_ptr> cache;

auto objPtr = cache[id].lock(); // objPtr is std::shared_ptr

// to cached object (or null

// if object's not in cache)

if (!objPtr) { // if not in cache,

objPtr = loadWidget(id); // load it

cache[id] = objPtr; // cache it

}

return objPtr;

}

This implementation employs one of C++11's hash table containers ( std::unordered_map), though it doesn't show the WidgetIDhashing and equality-comparison functions that would also have to be present.

The implementation of fastLoadWidgetignores the fact that the cache may accumulate expired std::weak_ptrs corresponding to Widgets that are no longer in use (and have therefore been destroyed). The implementation can be refined, but rather than spend time on an issue that lends no additional insight into std::weak_ptrs, let's consider a second use case: the Observer design pattern. The primary components of this pattern are subjects (objects whose state may change) and observers (objects to be notified when state changes occur). In most implementations, each subject contains a data member holding pointers to its observers. That makes it easy for subjects to issue state change notifications. Subjects have no interest in controlling the lifetime of their observers (i.e., when they're destroyed), but they have a great interest in making sure that if an observer gets destroyed, subjects don't try to subsequently access it. A reasonable design is for each subject to hold a container of std::weak_ptrs to its observers, thus making it possible for the subject to determine whether a pointer dangles before using it.

As a final example of std::weak_ptr's utility, consider a data structure with objects A, B, and Cin it, where Aand Cshare ownership of Band therefore hold std::shared_ptrs to it:

Suppose itd be useful to also have a pointer from Bback to A What kind of - фото 4

Suppose it'd be useful to also have a pointer from Bback to A. What kind of pointer should this be?

There are three choices A raw pointer With this approach if Ais destroyed - фото 5

There are three choices:

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Effective Modern C++»

Представляем Вашему вниманию похожие книги на «Effective Modern C++» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Effective Modern C++»

Обсуждение, отзывы о книге «Effective Modern C++» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x