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

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

Интервал:

Закладка:

Сделать

constexprdouble yValue() const noexcept { return y; }

void setX(double newX) noexcept { x = newX; }

void setY(double newY) noexcept { y = newY; }

private:

double x, y;

};

Here, the Pointconstructor can be declared constexpr, because if the arguments passed to it are known during compilation, the value of the data members of the constructed Pointcan also be known during compilation. Points so initialized could thus be constexpr:

constexprPoint p1(9.4, 27.7); // fine, "runs" constexpr

// ctor during compilation

constexprPoint p2(28.8, 5.3); // also fine

Similarly, the getters xValueand yValuecan be constexpr, because if they're invoked on a Pointobject with a value known during compilation (e.g., a constexpr Pointobject), the values of the data members xand ycan be known during compilation. That makes it possible to write constexprfunctions that call Point's getters and to initialize constexprobjects with the results of such functions:

constexpr

Point midpoint(const Point& p1, const Point& p2) noexcept

{

return { (p1. xValue()+ p2. xValue()) / 2, // call constexpr

(p1. yValue()+ p2. yValue()) / 2 }; // member funcs

}

constexprauto mid = midpoint(p1, p2); // init constexpr

// object w/result of

// constexpr function

This is very exciting. It means that the object mid, though its initialization involves calls to constructors, getters, and a non-member function, can be created in readonly memory! It means you could use an expression like mid.xValue() * 10in an argument to a template or in an expression specifying the value of an enumerator! [6] Because Point::xValue returns double , the type of mid.xValue() * 10 is also double . Floating-point types can't be used to instantiate templates or to specify enumerator values, but they can be used as part of larger expressions that yield integral types. For example, static_cast(mid.xValue() * 10) could be used to instantiate a template or to specify an enumerator value. It means that the traditionally fairly strict line between work done during compilation and work done at runtime begins to blur, and some computations traditionally done at runtime can migrate to compile time. The more code taking part in the migration, the faster your software will run. (Compilation may take longer, however.)

In C++11, two restrictions prevent Point's member functions setXand setYfrom being declared constexpr. First, they modify the object they operate on, and in C++11, constexprmember functions are implicitly const. Second, they have voidreturn types, and voidisn't a literal type in C++11. Both these restrictions are lifted in C++14, so in C++14, even Point's setters can be constexpr:

class Point {

public:

constexprvoid setX(double newX) noexcept // C++14

{ x = newX; }

constexprvoid setY(double newY) noexcept // C++14

{ y = newY; }

};

That makes it possible to write functions like this:

// return reflection of p with respect to the origin (C++14)

constexpr Point reflection(const Point& p) noexcept {

Point result; // create non-const Point

result. setX(-p.xValue()); // set its x and y values

result. setY(-p.yValue());

return result; // return copy of it

}

Client code could look like this:

constexpr Point p1(9.4, 27.7); // as above

constexpr Point p2(28.8, 5.3);

constexpr auto mid = midpoint(p1, p2);

constexpr auto reflectedMid = // reflectedMid's value is

reflection(mid); // (-19.1 -16.5) and known

// during compilation

The advice of this Item is to use constexprwhenever possible, and by now I hope it's clear why: both constexprobjects and constexprfunctions can be employed in a wider range of contexts than non- constexprobjects and functions. By using constexprwhenever possible, you maximize the range of situations in which your objects and functions may be used.

It's important to note that constexpris part of an object's or function's interface. constexprproclaims “I can be used in a context where C++ requires a constant expression.” If you declare an object or function constexpr, clients may use it in such contexts. If you later decide that your use of constexprwas a mistake and you remove it, you may cause arbitrarily large amounts of client code to stop compiling. (The simple act of adding I/O to a function for debugging or performance tuning could lead to such a problem, because I/O statements are generally not permitted in constexprfunctions.) Part of “whenever possible” in “Use constexprwhenever possible” is your willingness to make a long-term commitment to the constraints it imposes on the objects and functions you apply it to.

Things to Remember

constexprobjects are constand are initialized with values known during compilation.

constexprfunctions can produce compile-time results when called with arguments whose values are known during compilation.

constexprobjects and functions may be used in a wider range of contexts than non- constexprobjects and functions.

constexpris part of an object's or function's interface.

Item 16: Make constmember functions thread safe.

If we're working in a mathematical domain, we might find it convenient to have a class representing polynomials. Within this class, it would probably be useful to have a function to compute the root(s) of a polynomial, i.e., values where the polynomial evaluates to zero. Such a function would not modify the polynomial, so it'd be natural to declare it const:

class Polynomial {

public:

using RootsType = // data structure holding values

std::vector; // where polynomial evals to zero

… // (see Item 9 for info on "using")

RootsType roots() const;

};

Computing the roots of a polynomial can be expensive, so we don't want to do it if we don't have to. And if we do have to do it, we certainly don't want to do it more than once. We'll thus cache the root(s) of the polynomial if we have to compute them, and we'll implement rootsto return the cached value. Here's the basic approach:

class Polynomial {

public:

using RootsType = std::vector;

RootsType roots() const {

if (!rootsAreValid) { // if cache not valid

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

Интервал:

Закладка:

Сделать

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

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


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

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