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::unique_ptrembodies exclusive ownership semantics. A non-null std::unique_ptralways owns what it points to. Moving a std::unique_ptrtransfers ownership from the source pointer to the destination pointer. (The source pointer is set to null.) Copying a std::unique_ptrisn't allowed, because if you could copy a std::unique_ptr, you'd end up with two std::unique_ptrs to the same resource, each thinking it owned (and should therefore destroy) that resource. std::unique_ptris thus a move-only type . Upon destruction, a non-null std::unique_ptrdestroys its resource. By default, resource destruction is accomplished by applying deleteto the raw pointer inside the std::unique_ptr.

A common use for std::unique_ptris as a factory function return type for objects in a hierarchy. Suppose we have a hierarchy for types of investments (e.g., stocks, bonds, real estate, etc.) with a base class Investment.

class Investment class Stock public Investment class Bond - фото 2

class Investment { … };

class Stock:

public Investment { … };

class Bond:

public Investment { … };

class RealEstate:

public Investment { … };

A factory function for such a hierarchy typically allocates an object on the heap and returns a pointer to it, with the caller being responsible for deleting the object when it's no longer needed. That's a perfect match for std::unique_ptr, because the caller acquires responsibility for the resource returned by the factory (i.e., exclusive ownership of it), and the std::unique_ptrautomatically deletes what it points to when the std::unique_ptris destroyed. A factory function for the Investmenthierarchy could be declared like this:

template // return std::unique_ptr

std::unique_ptr // to an object created

makeInvestment(Ts&&... params); // from the given args

Callers could use the returned std::unique_ptrin a single scope as follows,

{

auto pInvestment = // pInvestment is of type

makeInvestment( arguments ); // std::unique_ptr

} // destroy *pInvestment

but they could also use it in ownership-migration scenarios, such as when the std::unique_ptrreturned from the factory is moved into a container, the container element is subsequently moved into a data member of an object, and that object is later destroyed. When that happens, the object's std::unique_ptrdata member would also be destroyed, and its destruction would cause the resource returned from the factory to be destroyed. If the ownership chain got interrupted due to an exception or other atypical control flow (e.g., early function return or breakfrom a loop), the std::unique_ptrowning the managed resource would eventually have its destructor called, [7] There are a few exceptions to this rule. Most stem from abnormal program termination. If an exception propagates out of a thread's primary function (e.g., main , for the program's initial thread) or if a noexcept specification is violated (see Item 14 ), local objects may not be destroyed, and if std::abort or an exit function (i.e., std::_Exit , std::exit , or std::quick_exit ) is called, they definitely won't be. and the resource it was managing would thereby be destroyed.

By default, that destruction would take place via delete, but, during construction, std::unique_ptrobjects can be configured to use custom deleters : arbitrary functions (or function objects, including those arising from lambda expressions) to be invoked when it's time for their resources to be destroyed. If the object created by makeInvestmentshouldn't be directly deleted, but instead should first have a log entry written, makeInvestmentcould be implemented as follows. (An explanation follows the code, so don't worry if you see something whose motivation is less than obvious.)

auto delInvmt = [](Investment* pInvestment) // custom

{ // deleter

makeLogEntry(pInvestment); // (a lambda

delete pInvestment; // expression)

};

template // revised

std::unique_ptr // return type

makeInvestment(Ts&&... params) {

std::unique_ptr // ptr to be

pInv(nullptr, delInvmt); // returned

if ( /* a Stock object should be created */ ) {

pInv.reset(new Stock(std::forward(params)...));

}

else if ( /* a Bond object should be created */ ) {

pInv.reset(new Bond(std::forward(params)...));

}

else if ( /* a RealEstate object should be created */ ){

pInv.reset(new RealEstate(std::forward(params)...));

}

return pInv;

}

In a moment, I'll explain how this works, but first consider how things look if you're a caller. Assuming you store the result of the makeInvestmentcall in an autovariable, you frolic in blissful ignorance of the fact that the resource you're using requires special treatment during deletion. In fact, you veritably bathe in bliss, because the use of std::unique_ptrmeans you need not concern yourself with when the resource should be destroyed, much less ensure that the destruction happens exactly once along every path through the program. std::unique_ptrtakes care of all those things automatically. From a client's perspective, makeInvestment's interface is sweet.

The implementation is pretty nice, too, once you understand the following:

delInvmtis the custom deleter for the object returned from makeInvestment. All custom deletion functions accept a raw pointer to the object to be destroyed, then do what is necessary to destroy that object. In this case, the action is to call makeLogEntryand then apply delete. Using a lambda expression to create delInvmtis convenient, but, as we'll see shortly, it's also more efficient than writing a conventional function.

• When a custom deleter is to be used, its type must be specified as the second type argument to std::unique_ptr. In this case, that's the type of delInvmt, and that's why the return type of makeInvestmentis std::unique_ptr. (For information about decltype, see Item 3.)

• The basic strategy of makeInvestmentis to create a null std::unique_ptr, make it point to an object of the appropriate type, and then return it. To associate the custom deleter delInvmtwith pInv, we pass that as its second constructor argument.

• Attempting to assign a raw pointer (e.g., from new) to a std::unique_ptrwon't compile, because it would constitute an implicit conversion from a raw to a smart pointer. Such implicit conversions can be problematic, so C++11's smart pointers prohibit them. That's why resetis used to have pInvassume ownership of the object created via new.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x