Thinking in C++第2版第一卷读书笔记

<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;"><a href="http://download.csdn.net/source/1214117">《Thinking in C++》PDF电子书</a></span></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">中先编译,后连接:</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">编译:将源码编译为代码;</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">连接:将库函数和各种自定义函数依次连接成为一个可执行文件。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">中</span><span lang="EN-US"><span style="font-family: Calibri;">include</span></span><span style="">不再使用</span><span lang="EN-US"><span style="font-family: Calibri;">.h</span></span><span style="">后缀</span><span lang="EN-US"><span style="font-family: Calibri;">#include &lt;stdio.h&gt; </span></span><span style="">变在了</span><span lang="EN-US"><span style="font-family: Calibri;">#include &lt;cstdio&gt;</span></span><span style="">。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">#include&lt;cstdlib&gt;</span></span><span style="">调用程序(控制台方式):</span><span lang="EN-US"><span style="font-family: Calibri;">system(“</span></span><span style="">程序名</span><span lang="EN-US"><span style="font-family: Calibri;">”);</span></span><span style="">。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">#include &lt;fstream&gt;ifstream in(“</span></span><span style="">文件名</span><span lang="EN-US"><span style="font-family: Calibri;">”);//</span></span><span style="">打开文件以备读取</span><span lang="EN-US"><span style="font-family: Calibri;">ifstream out(“</span></span><span style="">文件名</span><span lang="EN-US"><span style="font-family: Calibri;">”);//</span></span><span style="">打开文件以备写入。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">#include &lt;vector&gt;vector</span></span><span style="">是一个类似</span><span lang="EN-US"><span style="font-family: Calibri;">List</span></span><span style="">的容器,是范型的。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">定义指针函数:</span><span lang="EN-US"><span style="font-family: Calibri;"> void (*funcPtr)()</span></span><span style="">,注意:</span><span lang="EN-US"><span style="font-family: Calibri;">void *funcPtr()</span></span><span style="">是返回</span><span lang="EN-US"><span style="font-family: Calibri;">void*</span></span><span style="">的函数。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">right-left guideline</span></span><span style="">:对指针采用先右结合,后左结合的解读方法。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">可能释放资源要注意,可能有的指针会指向已经释放的地址。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">数组</span><span lang="EN-US"><span style="font-family: Calibri;">c[]</span></span><span style="">的长度</span><span lang="EN-US"><span style="font-family: Calibri;">sizeof c/sizeof *c</span></span><span style="">:</span><span lang="EN-US"><span style="font-family: Calibri;">sizeof c</span></span><span style="">是总长,</span><span lang="EN-US"><span style="font-family: Calibri;">sizeof *c</span></span><span style="">是第一元素的长度。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">匿名:可以匿名</span><span lang="EN-US"><span style="font-family: Calibri;">union</span></span><span style="">、参数。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">默认情况下</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">:在</span><span lang="EN-US"><span style="font-family: Calibri;">C</span></span><span style="">中是外部链接级而</span><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">中是文件内部链接级。所以要在定义</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">变量之外的文件中使用</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">,那么要在定义和引用时都声名</span><span lang="EN-US"><span style="font-family: Calibri;">extern</span></span><span style="">,如:</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">extern int a = 1;//</span></span><span style="">定义</span><span lang="EN-US"><span style="font-family: Calibri;"><span style=""> </span>extern int a;//</span></span><span style="">声名。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">在</span><span lang="EN-US"><span style="font-family: Calibri;">C</span></span><span style="">中总是给</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">分配空间,而</span><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">中只有无法编译时确定</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">值时才被迫为其分配空间。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">const int* x; int const* x;//</span></span><span style="">指向常量的指针,</span><span lang="EN-US"><span style="font-family: Calibri;">*</span></span><span style="">先和右边结合。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">int* const x;//</span></span><span style="">常量指针</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">int const*const x; </span></span><span style="font-family: Wingdings;" lang="EN-US"><span style="">ó</span></span><span lang="EN-US"><span style="font-family: Calibri;"> const int* const x;//</span></span><span style="">指向常量的常量指针</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">字符数组指针(</span><span lang="EN-US"><span style="font-family: Calibri;">char* p = “abc”;</span></span><span style="">)类型实际上是常量字符数组。如果想使数组不是常量,那么使用数组形式的定义</span><span lang="EN-US"><span style="font-family: Calibri;">char p[] = “abc”;</span></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">常量不能做左值。函数返回常量不能作为非常量的右值(</span><span lang="EN-US"><span style="font-family: Calibri;">int* ip = w();//</span></span><span style="">不合法,</span><span lang="EN-US"><span style="font-family: Calibri;">w()</span></span><span style="">返回</span><span lang="EN-US"><span style="font-family: Calibri;">const int*</span></span><span style="">)。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">类中声名成员函数为常函数,</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">关键字放在函数名</span><span lang="EN-US"><span style="font-family: Calibri;">()</span></span><span style="">的后面。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">不改变类成员的函数都应声名为常函数。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">类对象只能调用</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">成员函数,</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">成员函数只能修改</span><span lang="EN-US"><span style="font-family: Calibri;">mutable</span></span><span style="">成员变量(如</span><span lang="EN-US"><span style="font-family: Calibri;">mutable int i;</span></span><span style="">)。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">int function(const T&amp; a){}//</span></span><span style="">强制不允许改变</span><span lang="EN-US"><span style="font-family: Calibri;">a</span></span><span style="">的内容,如果函数内修改</span><span lang="EN-US"><span style="font-family: Calibri;">a</span></span><span style="">,则进行拷贝构造。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">volatile</span></span><span style="">:编译时不优化。用法类似</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">。只有</span><span lang="EN-US"><span style="font-family: Calibri;">volatile</span></span><span style="">成员函数可以访问</span><span lang="EN-US"><span style="font-family: Calibri;">volatile</span></span><span style="">成员变量。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">定义</span><span lang="EN-US"><span style="font-family: Calibri;">class</span></span><span style="">时,在</span><span lang="EN-US"><span style="font-family: Calibri;">class</span></span><span style="">定义内直接给出函数定义的函数自动成为</span><span lang="EN-US"><span style="font-family: Calibri;">inline</span></span><span style="">函数,而无须使用关键字。如不想使用内联方式,则单独定义函数。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">inline</span></span><span style="">关键字不起作用的两种情况:</span><span lang="EN-US"><span style="font-family: Calibri;">1.</span></span><span style="">函数体过于复杂;</span><span lang="EN-US"><span style="font-family: Calibri;">2.</span></span><span style="">函数地址被明引或暗引。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">using declares//</span></span><span style="">指明名空间内具体的一个函数之类。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">using directive//</span></span><span style="">引用名空间。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">static const</span></span><span style="">数组的定义必须放在类定义外,</span><span lang="EN-US"><span style="font-family: Calibri;">static const</span></span><span style="">类型中,只有</span><span lang="EN-US"><span style="font-family: Calibri;">int</span></span><span style="">的定义可以放在类定义内,并且</span><span lang="EN-US"><span style="font-family: Calibri;">int</span></span><span style="">数组也必须要类定义外定义,其余内置和自定义类型都不可在类定义内定义。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">static initialization dependency</span></span><span style="">:静态初始化依赖,当依赖者比被依赖者先初始化时会出错:</span></span></p>
<p class="MsoListParagraph" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small; font-family: Calibri;">1.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><span style="font-size: small;">别使用静态依赖</span></span></p>
<p class="MsoListParagraph" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small; font-family: Calibri;">2.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><span style="font-size: small;">将静态引用全部列入一个中间文件</span></span></p>
<p class="MsoListParagraph" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small; font-family: Calibri;">3.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style=""><span style="font-size: small;">以上两种还无法解决此问题:</span></span></p>
<p class="MsoListParagraph" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small; font-family: Calibri;">a)</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="">使用静态初始化头文件初始化静态类型,在要使用的地方引用此</span><span lang="EN-US"><span style="font-family: Calibri;">.h</span></span><span style="">文件。这时这个</span><span lang="EN-US"><span style="font-family: Calibri;">.h</span></span><span style="">文件中的对象只在本文件中可用,再有其他文件引用此</span><span lang="EN-US"><span style="font-family: Calibri;">.h</span></span><span style="">文件时,因为要引用的类型是</span><span lang="EN-US"><span style="font-family: Calibri;">static</span></span><span style="">的,编译器会为其他文件分配单独的引用类型实例。</span></span></p>
<p class="MsoListParagraph" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small; font-family: Calibri;">b)</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="">将静态类型包装到函数当中,使用之前调用函数强制初始化(因为静态类型只初始化一次,注意:此时函数的实现不可在</span><span lang="EN-US"><span style="font-family: Calibri;">.h</span></span><span style="">文件中采用内联方式,因为内联函数会为每一个调用它的对象复制一个函数实例,使得静态类型不止一次初始化)。(推荐)</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">C++</span></span><span style="">中调用</span><span lang="EN-US"><span style="font-family: Calibri;">C</span></span><span style="">写的函数应使用如下方式声名:</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span lang="EN-US"><span style="font-family: Calibri;">extern “C” {#include “Myheader.h”}</span></span><span style="">,或者</span><span lang="EN-US"><span style="font-family: Calibri;">extern “C” {</span></span><span style="">各个函数声名</span><span lang="EN-US"><span style="font-family: Calibri;">}</span></span><span style="">,</span><span lang="EN-US"><span style="font-family: Calibri;">extern “C” </span></span><span style="">函数声名</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">引用必须定义时初始化。</span><span lang="EN-US"><span style="font-family: Calibri;">int x = 0; int&amp; a = x;//</span></span><span style="">此时表示</span><span lang="EN-US"><span style="font-family: Calibri;">a</span></span><span style="">是</span><span lang="EN-US"><span style="font-family: Calibri;">x</span></span><span style="">的一个别名,两者是等价的。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">引用方式传递参数:实际上是传递的对象的一个引用,函数中可以改变原对象的值。而</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">类型无法以引用方式传递(因为它没有地址,所以无法引用),所以要将函数形式参数声名为</span><span lang="EN-US"><span style="font-family: Calibri;">const</span></span><span style="">类型。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">编译器在需要时会构造临时对象,这种对象的生命期短到不会引发对象间的冲突。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">类内有类(组合</span><span lang="EN-US"><span style="font-family: Calibri;">Composite</span></span><span style="">)的情况下,内部类必须有外部类调用的构造函数。换句话说,编译器不会为内部类生成默认构造函数。当组合进行</span><span lang="EN-US"><span style="font-family: Calibri;">Composite a; Composite b = a;</span></span><span style="">时,</span><span lang="EN-US"><span style="font-family: Calibri;">Composite</span></span><span style="">及其内部类的拷贝构造函数都会被调用(如果没有的话,编译器会生成位拷贝型的拷贝构造函数)。所以最好为每个类自定义拷贝构造函数(</span><span lang="EN-US"><span style="font-family: Calibri;">X (X&amp;)</span></span><span style="">)以得到类的控制权。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">将拷贝构造函数定义为</span><span lang="EN-US"><span style="font-family: Calibri;">private</span></span><span style="">类型,可以避免系统自动生成拷贝构造函数。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">对类内函数使用指针及引用类内函数,最好将其封装在类内。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style=""><span style="font-size: small;">子类中重写(重定义或修改签名)父类中有重载函数(包括静态)的众函数之一时,会导致这个函数的其它重载在继承类中隐藏。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">子类使用父类中</span><span lang="EN-US"><span style="font-family: Calibri;">private</span></span><span style="">类型的方法:在</span><span lang="EN-US"><span style="font-family: Calibri;">public</span></span><span style="">模块中使用语句</span><span lang="EN-US"><span style="font-family: Calibri;">using </span></span><span style="">父类名</span><span lang="EN-US"><span style="font-family: Calibri;">::</span></span><span style="">函数名(不带括号)。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">面向对象程序设计语言的三大重要特性:</span><span lang="EN-US"><span style="font-family: Calibri;">1.data abstraction; 2. inheritance; 3. polymorphism.</span></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">对象切割(</span><span lang="EN-US"><span style="font-family: Calibri;">object slicing</span></span><span style="">),在传递对象时我们通常采用传地址,当传值时就会发生这样的现象,较大的对象传给较小的类</span><span lang="EN-US"><span style="font-family: Calibri;">by value</span></span><span style="">时,就会被截断。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: small;"><span style="">纯虚析构函数(</span><span lang="EN-US"><span style="font-family: Calibri;">pure virtual destructor</span></span><span style="">)必须提供定义,因为它比一般函数特殊。</span></span></p>
<p><span style="">在析构函数内部调用的函数,只调用本地版本,虚机制会被略过,以确保安全。</span></p>

你可能感兴趣的:(读书笔记)