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

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

Интервал:

Закладка:

Сделать

Widget& operator=(Widget&& rhs);// only

private: // as before

struct Impl;

std::unique_ptr pImpl;

};

#include // as before,

… // in "widget.cpp"

struct Widget::Impl { … }; // as before

Widget::Widget() // as before

: pImpl(std::make_unique())

{}

Widget::~Widget() = default; // as before

Widget::Widget(Widget&& rhs) = default; // defini-

Widget& Widget::operator=(Widget&& rhs) = default;// tions

The Pimpl Idiom is a way to reduce compilation dependencies between a class's implementation and the class's clients, but, conceptually, use of the idiom doesn't change what the class represents. The original Widgetclass contained std::string, std::vector, and Gadgetdata members, and, assuming that Gadgets, like std::strings and std::vectors, can be copied, it would make sense for Widgetto support the copy operations. We have to write these functions ourselves, because (1) compilers won't generate copy operations for classes with move-only types like std::unique_ptrand (2) even if they did, the generated functions would copy only the std::unique_ptr(i.e., perform a shallow copy ), and we want to copy what the pointer points to (i.e., perform a deep copy ).

In a ritual that is by now familiar, we declare the functions in the header file and implement them in the implementation file:

class Widget { // still in "widget.h"

public:

… // other funcs, as before

Widget(const Widget& rhs); // declarations

Widget& operator=(const Widget& rhs);// only

private: // as before

struct Impl;

std::unique_ptr pImpl;

};

#include "widget.h" // as before,

… // in "widget.cpp"

struct Widget::Impl { … }; // as before

Widget::~Widget() = default; // other funcs, as before

Widget::Widget(const Widget& rhs) // copy ctor

: pImpl(std::make_unique(*rhs.pImpl))

{}

Widget& Widget::operator=(const Widget& rhs)// copy operator=

{

*pImpl = *rhs.pImpl;

return *this;

}

Both function implementations are conventional. In each case, we simply copy the fields of the Implstruct from the source object ( rhs) to the destination object ( *this). Rather than copy the fields one by one, we take advantage of the fact that compilers will create the copy operations for Impl, and these operations will copy each field automatically. We thus implement Widget's copy operations by calling Widget::Impl's compiler-generated copy operations. In the copy constructor, note that we still follow the advice of Item 21to prefer use of std::make_uniqueover direct use of new.

For purposes of implementing the Pimpl Idiom, std::unique_ptris the smart pointer to use, because the pImplpointer inside an object (e.g., inside a Widget) has exclusive ownership of the corresponding implementation object (e.g., the Widget::Implobject). Still, it's interesting to note that if we were to use std::shared_ptrinstead of std::unique_ptrfor pImpl, we'd find that the advice of this Item no longer applied. There'd be no need to declare a destructor in Widget, and without a user-declared destructor, compilers would happily generate the move operations, which would do exactly what we'd want them to. That is, given this code in widget.h,

class Widget { // in "widget.h"

public:

Widget();

… // no declarations for dtor

// or move operations

private:

struct Impl;

std::shared_ptr<Impl >pImpl; // std::shared_ptr

}; // instead of std::unique_ptr

and this client code that #includes widget.h,

Widget w1;

auto w2(std::move(w1)); // move-construct w2

w1 = std::move(w2); // move-assign w1

everything would compile and run as we'd hope: w1would be default constructed, its value would be moved into w2, that value would be moved back into w1, and then both w1and w2would be destroyed (thus causing the pointed-to Widget::Implobject to be destroyed).

The difference in behavior between std::unique_ptrand std::shared_ptrfor pImplpointers stems from the differing ways these smart pointers support custom deleters. For std::unique_ptr, the type of the deleter is part of the type of the smart pointer, and this makes it possible for compilers to generate smaller runtime data structures and faster runtime code. A consequence of this greater efficiency is that pointed-to types must be complete when compiler-generated special functions (e.g., destructors or move operations) are used. For std::shared_ptr, the type of the deleter is not part of the type of the smart pointer. This necessitates larger runtime data structures and somewhat slower code, but pointed-to types need not be complete when compiler-generated special functions are employed.

For the Pimpl Idiom, there's not really a trade-off between the characteristics of std::unique_ptrand std::shared_ptr, because the relationship between classes like Widgetand classes like Widget::Implis exclusive ownership, and that makes std::unique_ptrthe proper tool for the job. Nevertheless, it's worth knowing that in other situations — situations where shared ownership exists (and std::shared_ptris hence a fitting design choice), there's no need to jump through the function-definition hoops that use of std::unique_ptrentails.

Things to Remember

• The Pimpl Idiom decreases build times by reducing compilation dependencies between class clients and class implementations.

• For std::unique_ptr pImplpointers, declare special member functions in the class header, but implement them in the implementation file. Do this even if the default function implementations are acceptable.

• The above advice applies to std::unique_ptr, but not to std::shared_ptr.

Chapter 5

Rvalue References, Move Semantics, and Perfect Forwarding

When you first learn about them, move semantics and perfect forwarding seem pretty straightforward:

Move semanticsmakes it possible for compilers to replace expensive copying operations with less expensive moves. In the same way that copy constructors and copy assignment operators give you control over what it means to copy objects, move constructors and move assignment operators offer control over the semantics of moving. Move semantics also enables the creation of move-only types, such as std::unique_ptr, std::future, and std::thread.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x