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

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

Интервал:

Закладка:

Сделать

Look again at this Item's title:

Consider pass by value for copyable parameters that are cheap to move and always copied.

It's worded the way it is for a reason. Four reasons, in fact:

1. You should only consider using pass by value. Yes, it requires writing only one function. Yes, it generates only one function in the object code. Yes, it avoids the issues associated with universal references. But it has a higher cost than the alternatives, and, as we'll see below, in some cases, there are expenses we haven't yet discussed.

2. Consider pass by value only for copyable parameters . Parameters failing this test must have move-only types, because if they're not copyable, yet the function always makes a copy, the copy must be created via the move constructor. [23] Sentences like this are why it'd be nice to have terminology that distinguishes copies made via copy operations from copies made via move operations. Recall that the advantage of pass by value over overloading is that with pass by value, only one function has to be written. But for move-only types, there is no need to provide an overload for lvalue arguments, because copying an lvalue entails calling the copy constructor, and the copy constructor for move-only types is disabled. That means that only rvalue arguments need to be supported, and in that case, the “overloading” solution requires only one overload: the one taking an rvalue reference.

Consider a class with a std::unique_ptrdata member and a setter for it. std::unique_ptris a move-only type, so the “overloading” approach to its setter consists of a single function:

class Widget {

public:

void setPtr( std::unique_ptr&&ptr)

{ p = std::move(ptr); }

private:

std::unique_ptr p;

};

A caller might use it this way:

Widget w;

w.setPtr( std::make_unique("Modern C++"));

Here the rvalue std::unique_ptrreturned from std::make_unique(see Item 21) is passed by rvalue reference to setPtr, where it's moved into the data member p. The total cost is one move.

If setPtrwere to take its parameter by value,

class Widget {

public:

void setPtr( std::unique_ptrptr)

{ p = std::move(ptr); }

};

the same call would move construct the parameter ptr, and ptrwould then be move assigned into the data member p. The total cost would thus be two moves — twice that of the “overloading” approach.

3. Pass by value is worth considering only for parameters that are cheap to move . When moves are cheap, the cost of an extra one may be acceptable, but when they're not, performing an unnecessary move is analogous to performing an unnecessary copy, and the importance of avoiding unnecessary copy operations is what led to the C++98 rule about avoiding pass by value in the first place!

4. You should consider pass by value only for parameters that are always copied . To see why this is important, suppose that before copying its parameter into the namescontainer, addNamechecks to see if the new name is too short or too long. If it is, the request to add the name is ignored. A pass-by-value implementation could be written like this:

class Widget {

public:

void addName(std::string newName) {

if ((newName.length() >= minLen) &&

(newName.length() <= maxLen)){

names.push_back(std::move(newName));

}

}

private:

std::vector names;

};

This function incurs the cost of constructing and destroying newName, even if nothing is added to names. That's a price the by-reference approaches wouldn't be asked to pay.

Even when you're dealing with a function performing an unconditional copy on a copyable type that's cheap to move, there are times when pass by value may not be appropriate. That's because a function can copy a parameter in two ways: via construction (i.e., copy construction or move construction) and via assignment (i.e., copy assignment or move assignment). addNameuses construction: its parameter newNameis passed to vector::push_back, and inside that function, newNameis copy constructed into a new element created at the end of the std::vector. For functions that use construction to copy their parameter, the analysis we saw earlier is complete: using pass by value incurs the cost of an extra move for both lvalue and rvalue arguments.

When a parameter is copied using assignment, the situation is more complicated. Suppose, for example, we have a class representing passwords. Because passwords can be changed, we provide a setter function, changeTo. Using a pass-by-value strategy, we could implement Passwordlike this:

class Password {

public:

explicit Password( std::string pwd) // pass by value

: text(std::move(pwd)){} // construct text

void changeTo( std::string newPwd) // pass by value

{ text = std::move(newPwd);} // assign text

private:

std::string text; // text of password

};

Storing the password as plain text will whip your software security SWAT team into a frenzy, but ignore that and consider this code:

std::string initPwd("Supercalifragilisticexpialidocious");

Password p(initPwd);

There are no suprises here: p.textis constructed with the given password, and using pass by value in the constructor incurs the cost of a std::stringmove construction that would not be necessary if overloading or perfect forwarding were employed. All is well.

A user of this program may not be as sanguine about the password, however, because “Supercalifragilisticexpialidocious” is found in many dictionaries. He or she may therefore take actions that lead to code equivalent to the following being executed:

std::string newPassword = "Beware the Jabberwock";

p.changeTo(newPassword);

Whether the new password is better than the old one is debatable, but that's the user's problem. Ours is that changeTo's use of assignment to copy the parameter newPwdprobably causes that function's pass-by-value strategy to explode in cost.

The argument passed to changeTois an lvalue ( newPassword), so when the parameter newPwdis constructed, it's the std::stringcopy constructor that's called. That constructor allocates memory to hold the new password. newPwdis then move-assigned to text, which causes the memory already held by textto be deallocated. There are thus two dynamic memory management actions within changeTo: one to allocate memory for the new password, and one to deallocate the memory for the old password.

But in this case, the old password (“Supercalifragilisticexpialidocious”) is longer than the new one (“Beware the Jabberwock”), so there's no need to allocate or deallocate anything. If the overloading approach were used, it's likely that none would take place:

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

Интервал:

Закладка:

Сделать

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

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


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

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

x