<Item 1>View C++ as a federation of languages。

1、把C++看成4种子语言组成,即C、Object-Oriented C++、Template C++、The STL。

2、Things to Remember:Rules for effective C++ programming vary, depending on the part of C++ you are using.

因为C++有很多的编程范式,在项目开发过程中,明确规范怎么使用C++很重要,这样可以使整个团队尽量使用一样的风格,并把项目一直做下去

 <Item 2>Prefer consts, enums, and inlines to #defines。

3、prefer the compiler to the preprocessor。因为宏定义不会被编译到符号表里面去,因此会对问题的调试定位带来麻烦,同时宏定义不能进行面向对象的封装和私有化。

4、使用常量代替宏定义的时候需要注意两个点,

一个是定义指针常量的时候需要使用两个const,如

const char * const authorName = "Scott Meyers";

其中前一个const修饰char,后一个const修饰指针,可以逆着读authorName 是一个const指针,指向const的char常量

另一个是使用class-specific constant的时候,为了保持一个内存copy,需要使用static进行定义

 class GamePlayer {
 private:
 static const int NumTurns = 5; // constant declarationint scores[NumTurns]; // use of constant...
 };

What you see above is a declaration for NumTurns, not a definition. Usually, C++ requires that you provide a definition for anything you use, but class-specific constants that are static and of integral type (e.g., integers, char s, bool s) are an exception. As long as you don't take their address, you can declare them and use them without providing a definition. If you do take the address of a class constant, or if your compiler incorrectly insists on a definition even if you don't take the address, you provide a separate definition like this:

const int GamePlayer::NumTurns; // definition of NumTurns; see 2 // below for why no value is given

Because the initial value of class constants is provided where the constant is declared (e.g., NumTurns is initialized to 5 when it is declared), no initial value is permitted at the point of definition.(也可以声明的时候不给初值,而在定义的时候给初值)

Note, by the way, that there's no way to create a class-specific constant using a #define, because #define s don't respect scope.

5、the enum hack

 class GamePlayer {
 private:
 enum { NumTurns = 5 }; // "the enum hack" — makes
 // NumTurns a symbolic name for 5int scores[NumTurns]; // fine...
 };

First, the enum hack behaves in some ways more like a #define than a const does, and sometimes that's what you want. For example, it's legal to take the address of a const, but it's not legal to take the address of an enum, and it's typically not legal to take the address of a #define, either. If you don't want to let people get a pointer or reference to one of your integral constants, an enum is a good way to enforce that constraint.

A second reason to know about the enum hack is purely pragmatic. Lots of code employs it, so you need to recognize it when you see it. In fact, the enum hack is a fundamental technique of template metaprogramming

6、another common (mis)use of the #define directive is using it to implement macros that look like functions but that don't incur the overhead of a function call.

  // call f with the maximum of a and b#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))

替换为

 template<typename T> // because we don'tinline void callWithMax(const T&a,const T&b)// know what T is, we{ // pass by reference-to-f(a > b ? a : b); // const — see Item 20}

7、Given the availability of const s, enum s, and inline s, your need for the preprocessor (especially #define) is reduced, but it's not eliminated. #include remains essential, and #ifdef /#ifndef continue to play important roles in controlling compilation. It's not yet time to retire the preprocessor, but you should definitely give it long and frequent vacations.

8、Things to Remember:

 For simple constants, prefer const objects or enums to #define s.
 For function-like macros, prefer inline functions to #define s.

<Item 3>Use const whenever possible。

9、const施加了一个semantic constraint,并有编译器来保证,同时It allows you to communicate to both compilers and other programmers that a value should remain invariant.

10、下面两种语法格式含义一致都表示Widget 为const常量

 void f1(const Widget *pw); // f1 takes a pointer to a
 // constant Widget objectvoid f2(Widget const *pw); // so does f2

11、If you want an iterator that points to something that can't be modified (i.e., the STL analogue of a const T* pointer), you want a const_iterator :

 std::vector<int> vec;
 ...
 const std::vector<int>::iterator iter = // iter acts like a T* constvec.begin();
 *iter = 10; // OK, changes what iter points to++iter; // error! iter is conststd::vector<int>::const_iterator cIter = //cIter acts like a const T*vec.begin();
 *cIter = 10; // error! *cIter is const++cIter; // fine, changes cIter

12、Having a function return a constant value often makes it possible to reduce the incidence of client errors without giving up safety or efficiency.

 class Rational {... };
 const Rational operator*(const Rational& lhs, const Rational& rhs);
 Rational a, b, c;
 ...
 (a * b) = c; // invoke operator= on the
 // result of a*b!if (a * b = c)... // oops, meant to do a comparison!

13、The purpose of const on member functions is to identify which member functions may be invoked on const objects. Such member functions are important for two reasons. First, they make the interface of a class easier to understand. It's important to know which functions may modify an object and which may not. Second, they make it possible to work with const objects. That's a critical aspect of writing efficient code, because, as Item 20 explains, one of the fundamental ways to improve a C++ program's performance is to pass objects by reference-to-const. That technique is viable only if there are const member functions with which to manipulate the resulting const -qualified objects.

14、Many people overlook the fact that member functions differing only in their constness can be overloaded, but this is an important feature of C++.const objects most often arise in real programs as a result of being passed by pointer- or reference-to-const.

15、What does it mean for a member function to be const ? There are two prevailing notions: bitwise constness (also known as physical constness) and logical constness.The bitwise const camp believes that a member function is const if and only if it doesn't modify any of the object's data members (excluding those that are static), i.e., if it doesn't modify any of the bits inside the object.In fact, bitwise constness is C++'s definition of constness, and a const member function isn't allowed to modify any of the non-static data members of the object on which it is invoked.(对象中包含指针的时候,指针不变但是指针指向的数据可变)。Adherents to this philosophy argue that a const member function might modify some of the bits in the object on which it's invoked, but only in ways that clients cannot detect.mutable frees non-static data members from the constraints of bitwise constness:

class CTextBlock {
public:
...
std::size_t length() const;
private:
char *pText;
mutable std::size_t textLength; // these data members may
mutable bool lengthIsValid; // always be modified, even in
}; // const member functions
std::size_t CTextBlock::length() const
{
if (!lengthIsValid) {
textLength = std::strlen(pText); // now fine
lengthIsValid = true; // also fine
}
return textLength;
}

16、Avoiding Duplication in const and Non-const Member Functions

class TextBlock {
public:...const char& operator[](std::size_t position) const     // same as before
{.........return text[position];}char& operator[](std::size_t position)         // now just calls const op[]{return  const_cast<char&>(                         // cast away const on// op[]'s return type;static_cast<const TextBlock&>(*this)     // add const to *this's type;[position]                            // call const version of op[]);}
...
};

16、Things to Remember

 Declaring something const helps compilers detect usage errors. const can be applied to objects at any scope, to function parameters and return types, and to member functions as a whole.
 Compilers enforce bitwise constness, but you should program using conceptual constness.
 When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

<Item 4> Make sure that objects are initialized before they're used

17、The rules of C++ stipulate that data members of an object are initialized before the body of a constructor is entered.参数初始化列表才是真实的初始化过程,构造函数内部的赋值不是初始化。For objects of built-in type like numTimesConsulted, there is no difference in cost between initialization and assignment, but for consistency, it's often best to initialize everything via member initialization.

18、Sometimes the initialization list must be used, even for built-in types. For example, data members that are const or are references must be initialized; they can't be assigned

19、当有很多成员或者基类需要初始化的时候,it's not unreasonable to omit entries in the lists for data members where assignment works as well as true initialization, moving the assignments to a single (typically private) function that all the constructors call.

20、One aspect of C++ that isn't fickle is the order in which an object's data is initialized. This order is always the same: base classes are initialized before derived classes (see also Item 12), and within a class, data members are initialized in the order in which they are declared.  成员初始化的顺序和初始化列表中的顺序无关,但是建议初始化列表中的数据和声明的顺序一致,以免读者误解

21、A static object is one that exists from the time it's constructed until the end of the program. Stack and heap-based objects are thus excluded. Included are global objects, objects defined at namespace scope, objects declared static inside classes, objects declared static inside functions, and objects declared static at file scope. Static objects inside functions are known as local static objects (because they're local to a function), and the other kinds of static objects are known as non-local static objects. Static objects are automatically destroyed when the program exits, i.e., their destructors are automatically called when main finishes executing.

22、A translation unit is the source code giving rise to a single object file. It's basically a single source file, plus all of its #include files.

23、The problem we're concerned with, then, involves at least two separately compiled source files, each of which contains at least one non-local static object (i.e., an object that's global, at namespace scope, or static in a class or at file scope). And the actual problem is this: if initialization of a non-local static object in one translation unit uses a non-local static object in a different translation unit, the object it uses could be uninitialized, because the relative order of initialization of non-local static objects defined in different translation units is undefined.解决方案是使用函数封装static变量确保初始化。This approach is founded on C++'s guarantee that local static objects are initialized when the object's definition is first encountered during a call to that function.

class FileSystem { ... };           // as before
FileSystem& tfs()                   // this replaces the tfs object; it could be
{                                   // static in the FileSystem classstatic FileSystem fs;             // define and initialize a local static objectreturn fs;                        // return a reference to it

}class Directory { ... };            // as before
Directory::Directory( params )      // as before, except references to tfs are
{                                   // now to tfs()...std::size_t disks = tfs().numDisks();  //使用函数封装确保初始化...
}Directory& tempDir()                // this replaces the tempDir object; it
{                                   // could be static in the Directory classstatic Directory td;              // define/initialize local static objectreturn td;                        // return reference to it
}

24、On the other hand, the fact that these functions contain static objects makes them problematic in multithreaded systems. Then again, any kind of non-const static object — local or non-local — is trouble waiting to happen in the presence of multiple threads. One way to deal with such trouble is to manually invoke all the reference-returning functions during the single-threaded startup portion of the program. This eliminates initialization-related race conditions.

25、Things to Remember
 Manually initialize objects of built-in type, because C++ only sometimes initializes them itself.
 In a constructor, prefer use of the member initialization list to assignment inside the body of the constructor. List data members in the initialization list in the same order they're declared in the class.
 Avoid initialization order problems across translation units by replacing non-local static objects with local static objects.

转载于:https://www.cnblogs.com/lshs/p/4396938.html

Effective C++读书摘要--Accustoming Youself to C++相关推荐

  1. Effective C++读书摘要--Implementations二

    <Item29> Strive for exception-safe code. 1.如下面的代码 class PrettyMenu { public:...void changeBack ...

  2. Effective C++读书笔记 摘自 pandawuwyj的专栏

    Effective C++读书笔记(0)       Start   声明式(Declaration):告诉编译器某个东西的名称和类型,但略去细节.   std::size_t numDigits(i ...

  3. linux读书摘要--正规表示法与文件格式化处理

    声明:本文章为<鸟哥的Linux私房菜>读书摘要! 正规表示法 正规表示法(Regular Expression, RE,或称为常规表示法)是透过一些特殊字符的排列,用以『搜寻/取代/删除 ...

  4. 《组织能力的杨三角》——企业持续成功的秘诀(杨国安)读书摘要

    序一摘要 宏基创办人施振荣 无论是流程改造,还是组织再造,甚至是经营策略,我们在实施变革时往往偏重策略本身或组织是否有效,以及员工是否了解,却忽略了他们是否认同和支持,也不知道员工是否具备了执行变革的 ...

  5. Effective Java读书笔记(二)

    Effective Java 读书笔记 (二) 创建和销毁对象 遇到多个构造器参数时要考虑使用构建器 创建和销毁对象 何时以及如何创建对象? 何时以及如何避免创建对象? 如何确保它们能够适时地销毁? ...

  6. Effective STL 读书笔记

    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

  7. 《原则》(瑞·达利欧)读书摘要

    <原则>(瑞·达利欧)读书摘要 P.S. 写个读书摘要,帮助没有读过<原则>的朋友做个简单的了解. 简介 全书前半是个人经历. 正片是生活原则+工作原则.极度理性,极度现实,极 ...

  8. more effective c++和effective c++读书笔记

    转载自http://bellgrade.blog.163.com/blog/static/83155959200863113228254/,方便日后自己查阅, More Effective C++读书 ...

  9. Effective Java 读书笔记(七):通用程序设计

    Effective Java 读书笔记七通用程序设计 将局部变量的作用域最小化 for-each 循环优于传统的 for 循环 了解和使用类库 如果需要精确的答案请避免使用 float 和 doubl ...

最新文章

  1. 稀缺:你是如何陷入贫穷与忙碌的
  2. 在Visual Studio 2005中安装Qt 4.3.2
  3. 用python查找指定格式或名称的文件及修改指定文件夹名称
  4. ssh 与 telnet 有何不同?_采用创新面料Nike Infinalon的全新瑜珈系列究竟有何不同?...
  5. .NET 4 并行(多核)编程系列之一入门介绍
  6. 从零开始玩人工智能-机器人服务-03
  7. Python for Informatics 第11章 正则表达式五(译)
  8. docker compose安装_docker stack,docker-compose前世今生
  9. 通讯录 按中文名字 拼音首字母 排序
  10. 找回 Windows 11 丢失的扫雷游戏【新春快乐】
  11. Java技术栈(跳槽,面试必备)
  12. vue+echarts 地图实现三级下钻
  13. 招聘时最看重应聘者的什么特质?
  14. matlab对三维矩阵求和,【求助】多维矩阵求和运算!!
  15. 标题一定要长~~~~长~~~~~~~~~~~~~~长~~~~~~~~
  16. 应用实践 | Apache Doris 在网易互娱的应用实践
  17. Xilinx ZYNQ Ultrascale+ 性能测试之 PL/PS PCIe Root Port NVMe
  18. getattr()函数解析
  19. java8的LocalDate、LocalDateTime和之前的Date、Calendar
  20. 电池上的PHP是什么,一次电池与二次电池的区别是什么?

热门文章

  1. JS确认提交confirm方法
  2. 定制填报提交的“确认”提示框
  3. 考研英语——唐迟阅读方法技巧总结
  4. DSP28系列—编写micros()微秒计数和millis()毫秒计数函数
  5. cad2016中选择全图字体怎么操作_ps创意字体设计教程:ps怎么做海报漂亮字体
  6. 最详细Vuex教程(超详细)-基本使用
  7. 关于语音识别技术的初探
  8. aix系统中514端口占用取消
  9. 2014工作报名+总结
  10. c# .net iot树莓派/香橙派用到物联网包Iot.Device.bindings 支持设备说明文档