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++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

std::shared_ptris the C++11 way of binding these worlds together. An object accessed via std::shared_ptrs has its lifetime managed by those pointers through shared ownership . No specific std::shared_ptrowns the object. Instead, all std::shared_ptrs pointing to it collaborate to ensure its destruction at the point where it's no longer needed. When the last std::shared_ptrpointing to an object stops pointing there (e.g., because the std::shared_ptris destroyed or made to point to a different object), that std::shared_ptrdestroys the object it points to. As with garbage collection, clients need not concern themselves with managing the lifetime of pointed-to objects, but as with destructors, the timing of the objects' destruction is deterministic.

A std::shared_ptrcan tell whether it's the last one pointing to a resource by consulting the resource's reference count , a value associated with the resource that keeps track of how many std::shared_ptrs point to it. std::shared_ptrconstructors increment this count (usually — see below), std::shared_ptrdestructors decrement it, and copy assignment operators do both. (If sp1and sp2are std::shared_ptrs to different objects, the assignment “ sp1 = sp2;” modifies sp1such that it points to the object pointed to by sp2. The net effect of the assignment is that the reference count for the object originally pointed to by sp1is decremented, while that for the object pointed to by sp2is incremented.) If a std::shared_ptrsees a reference count of zero after performing a decrement, no more std::shared_ptrs point to the resource, so the std::shared_ptrdestroys it.

The existence of the reference count has performance implications:

std::shared_ptr s are twice the size of a raw pointer, because they internally contain a raw pointer to the resource as well as a raw pointer to the resource's reference count. [8] This implementation is not required by the Standard, but every Standard Library implementation I'm familiar with employs it.

Memory for the reference count must be dynamically allocated. Conceptually, the reference count is associated with the object being pointed to, but pointed-to objects know nothing about this. They thus have no place to store a reference count. (A pleasant implication is that any object — even those of built-in types — may be managed by std::shared_ptrs.) Item 21explains that the cost of the dynamic allocation is avoided when the std::shared_ptris created by std::make_shared, but there are situations where std::make_sharedcan't be used. Either way, the reference count is stored as dynamically allocated data.

Increments and decrements of the reference count must be atomic, because there can be simultaneous readers and writers in different threads. For example, a std::shared_ptrpointing to a resource in one thread could be executing its destructor (hence decrementing the reference count for the resource it points to), while, in a different thread, a std::shared_ptrto the same object could be copied (and therefore incrementing the same reference count). Atomic operations are typically slower than non-atomic operations, so even though reference counts are usually only a word in size, you should assume that reading and writing them is comparatively costly.

Did I pique your curiosity when I wrote that std::shared_ptrconstructors only “usually” increment the reference count for the object they point to? Creating a std::shared_ptrpointing to an object always yields one more std::shared_ptrpointing to that object, so why mustn't we always increment the reference count?

Move construction, that's why. Move-constructing a std::shared_ptrfrom another std::shared_ptrsets the source std::shared_ptrto null, and that means that the old std::shared_ptrstops pointing to the resource at the moment the new std::shared_ptrstarts. As a result, no reference count manipulation is required. Moving std::shared_ptrs is therefore faster than copying them: copying requires incrementing the reference count, but moving doesn't. This is as true for assignment as for construction, so move construction is faster than copy construction, and move assignment is faster than copy assignment.

Like std::unique_ptr(see Item 18), std::shared_ptruses deleteas its default resource-destruction mechanism, but it also supports custom deleters. The design of this support differs from that for std::unique_ptr, however. For std::unique_ptr, the type of the deleter is part of the type of the smart pointer. For std::shared_ptr, it's not:

auto loggingDel = [](Widget *pw) // custom deleter

{ // (as in Item 18)

makeLogEntry(pw);

delete pw;

};

std::unique_ptr< // deleter type is

Widget, decltype(loggingDel) // part of ptr type

> upw(new Widget, loggingDel);

std::shared_ptr // deleter type is not

spw(new Widget, loggingDel); // part of ptr type

The std::shared_ptrdesign is more flexible. Consider two std::shared_ptrs, each with a custom deleter of a different type (e.g., because the custom deleters are specified via lambda expressions):

auto customDeleter1 = [](Widget *pw) { … }; // custom deleters,

auto customDeleter2 = [](Widget *pw) { … }; // each with a

// different type

std::shared_ptr pw1(new Widget, customDeleter1);

std::shared_ptr pw2(new Widget, customDeleter2);

Because pw1and pw2have the same type, they can be placed in a container of objects of that type:

std::vector> vpw{ pw1, pw2 };

They could also be assigned to one another, and they could each be passed to a function taking a parameter of type std::shared_ptr. None of these things can be done with std::unique_ptrs that differ in the types of their custom deleters, because the type of the custom deleter would affect the type of the std::unique_ptr.

In another difference from std::unique_ptr, specifying a custom deleter doesn't change the size of a std::shared_ptrobject. Regardless of deleter, a std::shared_ptrobject is two pointers in size. That's great news, but it should make you vaguely uneasy. Custom deleters can be function objects, and function objects can contain arbitrary amounts of data. That means they can be arbitrarily large. How can a std::shared_ptrrefer to a deleter of arbitrary size without using any more memory?

It can't. It may have to use more memory. However, that memory isn't part of the std::shared_ptrobject. It's on the heap or, if the creator of the std::shared_ptrtook advantage of std::shared_ptrsupport for custom allocators, it's wherever the memory managed by the allocator is located. I remarked earlier that a std::shared_ptrobject contains a pointer to the reference count for the object it points to. That's true, but it's a bit misleading, because the reference count is part of a larger data structure known as the control block . There's a control block for each object managed by std::shared_ptrs. The control block contains, in addition to the reference count, a copy of the custom deleter, if one has been specified. If a custom allocator was specified, the control block contains a copy of that, too. The control block may also contain additional data, including, as Item 21explains, a secondary reference count known as the weak count, but we'll ignore such data in this Item. We can envision the memory associated with a std::shared_ptrobject as looking like this:

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

Интервал:

Закладка:

Сделать

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

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


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

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

x