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::vector vs; // as before

… // add elements to vs

vs.emplace( vs.begin(), "xyzzy"); // add "xyzzy" to

// beginning of vs

For this code, few implementations will construct the added std::stringinto the memory occupied by vs[0]. Instead, they'll move-assign the value into place. But move assignment requires an object to move from, and that means that a temporary object will need to be created to be the source of the move. Because the primary advantage of emplacement over insertion is that temporary objects are neither created nor destroyed, when the value being added is put into the container via assignment, emplacement's edge tends to disappear.

Alas, whether adding a value to a container is accomplished by construction or assignment is generally up to the implementer. But, again, heuristics can help.

Node-based containers virtually always use construction to add new values, and most standard containers are node-based. The only ones that aren't are std::vector, std::deque, and std::string. ( std::arrayisn't, either, but it doesn't support insertion or emplacement, so it's not relevant here.) Within the non-node-based containers, you can rely on emplace_backto use construction instead of assignment to get a new value into place, and for std::deque, the same is true of emplace_front.

The argument type(s) being passed differ from the type held by the container. Again, emplacement's advantage over insertion generally stems from the fact that its interface doesn't require creation and destruction of a temporary object when the argument(s) passed are of a type other than that held by the container. When an object of type Tis to be added to a container , there's no reason to expect emplacement to run faster than insertion, because no temporary needs to be created to satisfy the insertion interface.

The container is unlikely to reject the new value as a duplicate. This means that the container either permits duplicates or that most of the values you add will be unique. The reason this matters is that in order to detect whether a value is already in the container, emplacement implementations typically create a node with the new value so that they can compare the value of this node with existing container nodes. If the value to be added isn't in the container, the node is linked in. However, if the value is already present, the emplacement is aborted and the node is destroyed, meaning that the cost of its construction and destruction was wasted. Such nodes are created for emplacement functions more often than for insertion functions.

The following calls from earlier in this Item satisfy all the criteria above. They also run faster than the corresponding calls to push_back.

vs.emplace_back("xyzzy"); // construct new value at end of

// container; don't pass the type in

// container; don't use container

// rejecting duplicates

vs.emplace_back(50, 'x'); // ditto

When deciding whether to use emplacement functions, two other issues are worth keeping in mind. The first regards resource management. Suppose you have a container of std::shared_ptrs,

std::list> ptrs;

and you want to add a std::shared_ptrthat should be released via a custom deleter (see Item 19). Item 21explains that you should use std::make_sharedto create std::shared_ptrs whenever you can, but it also concedes that there are situations where you can't. One such situation is when you want to specify a custom deleter. In that case, you must use newdirectly to get the raw pointer to be managed by the std::shared_ptr.

If the custom deleter is this function,

void killWidget(Widget* pWidget);

the code using an insertion function could look like this:

ptrs. push_back(std::shared_ptr(new Widget, killWidget));

It could also look like this, though the meaning would be the same:

ptrs. push_back({ new Widget, killWidget });

Either way, a temporary std::shared_ptrwould be constructed before calling push_back. push_back's parameter is a reference to a std::shared_ptr, so there has to be a std::shared_ptrfor this parameter to refer to.

The creation of the temporary std::shared_ptris what emplace_backwould avoid, but in this case, that temporary is worth far more than it costs. Consider the following potential sequence of events:

1. In either call above, a temporary std::shared_ptrobject is constructed to hold the raw pointer resulting from “ new Widget”. Call this object temp .

2. push_backtakes temp by reference. During allocation of a list node to hold a copy of temp , an out-of-memory exception gets thrown.

3. As the exception propagates out of push_back, temp is destroyed. Being the sole std::shared_ptrreferring to the Widgetit's managing, it automatically releases that Widget, in this case by calling killWidget.

Even though an exception occurred, nothing leaks: the Widgetcreated via “ new Widget” in the call to push_backis released in the destructor of the std::shared_ptrthat was created to manage it ( temp ). Life is good.

Now consider what happens if emplace_backis called instead of push_back:

ptrs. emplace_back(new Widget, killWidget);

1. The raw pointer resulting from “ new Widget” is perfect-forwarded to the point inside emplace_backwhere a list node is to be allocated. That allocation fails, and an out-of-memory exception is thrown.

2. As the exception propagates out of emplace_back, the raw pointer that was the only way to get at the Widgeton the heap is lost. That Widget(and any resources it owns) is leaked.

In this scenario, life is not good, and the fault doesn't lie with std::shared_ptr. The same kind of problem can arise through the use of std::unique_ptrwith a custom deleter. Fundamentally, the effectiveness of resource-managing classes like std::shared_ptrand std::unique_ptris predicated on resources (such as raw pointers from new) being immediately passed to constructors for resource-managing objects. The fact that functions like std::make_sharedand std::make_uniqueautomate this is one of the reasons they're so important.

In calls to the insertion functions of containers holding resource-managing objects (e.g., std::list>), the functions' parameter types generally ensure that nothing gets between acquisition of a resource (e.g., use of new) and construction of the object managing the resource. In the emplacement functions, perfect-forwarding defers the creation of the resource-managing objects until they can be constructed in the container's memory, and that opens a window during which exceptions can lead to resource leaks. All standard containers are susceptible to this problem. When working with containers of resource-managing objects, you must take care to ensure that if you choose an emplacement function over its insertion counterpart, you're not paying for improved code efficiency with diminished exception safety.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x