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

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

Интервал:

Закладка:

Сделать

• With each use of new, we use std::forwardto perfect-forward the arguments passed to makeInvestment(see Item 25). This makes all the information provided by callers available to the constructors of the objects being created.

• The custom deleter takes a parameter of type Investment*. Regardless of the actual type of object created inside makeInvestment(i.e., Stock, Bond, or RealEstate), it will ultimately be deleted inside the lambda expression as an Investment*object. This means we'll be deleting a derived class object via a base class pointer. For that to work, the base class — Investment— must have a virtual destructor:

class Investment {

public:

… // essential

virtual ~Investment();// design

… // component!

};

In C++14, the existence of function return type deduction (see Item 3) means that makeInvestmentcould be implemented in this simpler and more encapsulated fashion:

template

automakeInvestment(Ts&&... params) // C++14

{

auto delInvmt = [](Investment* pInvestment) // this is now

{ // inside

makeLogEntry(pInvestment); // make-

delete pInvestment; // Investment

};

std::unique_ptr // as

pInv(nullptr, delInvmt); // before

if ( … ) // as before

{

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

}

else if ( … ) // as before

{

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

}

else if ( … ) // as before

{

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

}

return pInv; // as before

}

I remarked earlier that, when using the default deleter (i.e., delete), you can reasonably assume that std::unique_ptrobjects are the same size as raw pointers. When custom deleters enter the picture, this may no longer be the case. Deleters that are function pointers generally cause the size of a std::unique_ptrto grow from one word to two. For deleters that are function objects, the change in size depends on how much state is stored in the function object. Stateless function objects (e.g., from lambda expressions with no captures) incur no size penalty, and this means that when a custom deleter can be implemented as either a function or a captureless lambda expression, the lambda is preferable:

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

{ // deleter

makeLogEntry(pInvestment); // as

delete pInvestment; // stateless

}; // lambda

template // return type

std::unique_ptr<Investment, decltype(delInvmt1)>// has size of

makeInvestment(Ts&&... args); // Investment*

void delInvmt2(Investment* pInvestment) // custom

{ // deleter

makeLogEntry(pInvestment); // as function

delete pInvestment;

}

template // return type has

std::unique_ptr<Investment, // size of Investment*

void (*)(Investment*)>// plus at least size

makeInvestment(Ts&&... params); // of function pointer!

Function object deleters with extensive state can yield std::unique_ptrobjects of significant size. If you find that a custom deleter makes your std::unique_ptrs unacceptably large, you probably need to change your design.

Factory functions are not the only common use case for std::unique_ptrs. They're even more popular as a mechanism for implementing the Pimpl Idiom. The code for that isn't complicated, but in some cases it's less than straightforward, so I'll refer you to Item 22, which is dedicated to the topic.

std::unique_ptrcomes in two forms, one for individual objects ( std::unique_ptr) and one for arrays ( std::unique_ptr). As a result, there's never any ambiguity about what kind of entity a std::unique_ptrpoints to. The std::unique_ptrAPI is designed to match the form you're using. For example, there's no indexing operator ( operator[]) for the single-object form, while the array form lacks dereferencing operators ( operator*and operator->).

The existence of std::unique_ptrfor arrays should be of only intellectual interest to you, because std::array, std::vector, and std::stringare virtually always better data structure choices than raw arrays. About the only situation I can conceive of when a std::unique_ptrwould make sense would be when you're using a C-like API that returns a raw pointer to a heap array that you assume ownership of.

std::unique_ptris the C++11 way to express exclusive ownership, but one of its most attractive features is that it easily and efficiently converts to a std::shared_ptr:

std::shared_ptrsp = // converts std::unique_ptr

makeInvestment( arguments ); // to std::shared_ptr

This is a key part of why std::unique_ptris so well suited as a factory function return type. Factory functions can't know whether callers will want to use exclusive-ownership semantics for the object they return or whether shared ownership (i.e., std::shared_ptr) would be more appropriate. By returning a std::unique_ptr, factories provide callers with the most efficient smart pointer, but they don't hinder callers from replacing it with its more flexible sibling. (For information about std::shared_ptr, proceed to Item 19.)

Things to Remember

std::unique_ptris a small, fast, move-only smart pointer for managing resources with exclusive-ownership semantics.

• By default, resource destruction takes place via delete, but custom deleters can be specified. Stateful deleters and function pointers as deleters increase the size of std::unique_ptrobjects.

• Converting a std::unique_ptrto a std::shared_ptris easy.

Item 19: Use std::shared_ptrfor shared-ownership resource management.

Programmers using languages with garbage collection point and laugh at what C++ programmers go through to prevent resource leaks. “How primitive!” they jeer. “Didn't you get the memo from Lisp in the 1960s? Machines should manage resource lifetimes, not humans.” C++ developers roll their eyes. “You mean the memo where the only resource is memory and the timing of resource reclamation is nondeterministic? We prefer the generality and predictability of destructors, thank you.” But our bravado is part bluster. Garbage collection really is convenient, and manual lifetime management really can seem akin to constructing a mnemonic memory circuit using stone knives and bear skins. Why can't we have the best of both worlds: a system that works automatically (like garbage collection), yet applies to all resources and has predictable timing (like destructors)?

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

Интервал:

Закладка:

Сделать

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

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


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

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