2012寒假《C++Primer》学习笔记

2012寒假《C++Primer》学习笔记

 

一章:

1.      在“位”一级上,存储器没有结构和意义,一个位置放0或者1,八位当块时才有意义。如:8个一块是一个字节,32个在一块是一个字(数据类型)。

2.      整型:表示整数/字符/布尔值的算术类型。

3.      值超过范围后则取该值对2该类型的取值个数(如:unsigned char 类型可以表示256个数(个数:256))求模的值。

4.       对象:内存中具有类型的区域。

5.      类型决定分配给变量的存储空间大小和其上的操作。

6.      初始化:直接初始化:int ival(1024);  复制初始化:intival=1024; 不是赋值!赋值:擦出当前的值,用新值代替!

7.      把变量定义在第一次使用它的地方。(定义) Int a=10;   (使用)cout<<a;

8.      Const:把一个对象传为一个常量!const变量定义后必须初始化,且在能在本文件中使用。

9.      引用:别名。符合类型。(int& , float&)引用必须用同类型的对象初始化。Int ival=1024;  int&refal=ival; 一个引用指向一个对象后不能指向别的对象。可多定义:int& r3=r2,&r4=i2;

10.  Const引用:指向const对象的引用。(只读)

11.  枚举对象初始化:赋值只能用枚举成员和同一枚举类型的其他对象。

12.  类定义:接口和实现::接口:操作(函数)。实现:数据。

13.  类:设计::1.从操作(函数或者功能)设计2.定义类(包括操作要用的数据)3.实现操作

14.  头文件是申明而不是定义。除(类定义/const对象/inline函数)

 

二章

1.      String索引值类型:string::size_type

2.      可以用整型坐下索引。不能将size的返回值赋给int型变量。

3.      Vector是一个模板,vector<int>是一个数据类型。

4.      用默认构造函数初始化容器中元素(包括无构造函数类型)

5.      用size_type时要说明类型:vector<int>::size_type a;  vector::size_type  a;

6.      Vector的下表操作不添加元素,因为是空的vector对象,而且下表只能用来获取已存在的元素。只能通过push_back();来添加元素。加在vector对象的后面。

7.      Vector两种访问结构:1.通过下表2.迭代器(数据类型)

8.      Constvector<int>::iterator  lit;  *lit=1;(RIGHT) lit++;(ERROR!)  vector<int>::const_iterator lit;   lit++;(RIGHT) *lit=2;(ERROR!)  

9.      Bitset:类模板。定义时,明确有多少位。

10.  (内置/低级) 数组 == vector  指针------iterator  (高级/标准库)

11.   const以及运行时才知道大小的书不能初始化数组。

12.  数组大小固定。

13.  指针一定要初始化。

14.  Int aa=0;  const int aa1=0;  int* b=aa; (ERROR)  int* b=aa1;(RIGHT).

15.  不允许void* 指针操作操作他所指对象。

16.  Void*指针只有三个操作:1.给另一个void*指针赋值2.(给函数传递void*指针)从函数返回void*指针3.与另一个指针进行比较。

17.  指针是间接操作对象的(先去地址)

18.  引用与指针:1.引用总是指向某个对象,必须初始化。2.赋值的不同。

19.  表达书中使用数组名时,名字会自动转换为指向该数组的第一个元素的指针。

20.  指向数组某一元素:int * ip=&a[4];

 

1.        Int ia[]={1,2,3,4};  int* p=ia; int* pi=p+3;//新指针  *(p+3)=4;

2.        两个指针相减是相间隔对象个数。

3.        数组名:指向数组第一个元素的指针。下表访问:访问指针。P[1]==等同于===*(p+1)

4.        指向const对象的指针也必须是const的。Const double pi=3.14; douple* pti=&pi;(ERROR!pti可改变(指向别的值,不可以通过指针改变pi(对象)))           const double *pi2=&pi;(RIGHT)   const void*cp=&pi;(RIOGHT)   const 离谁近谁不可以变。可以把非const对象的地址给指向const对象的指针:doubledva=3.14; const double* cp; cp=&dva; (但是不可以改变通过指针改变dva的值)

 

 

1.        动态分配在堆上。Int* pia=new int[10](初始化);

2.        释放动态分配的数组空间 delete []pia;

3.        数组指针:参考《C深度剖析》 PDF文件。

 

 

1.        优先级:政正负(+/--),(*/%)二元(+--

2.        只能对整型求余(bool,char,short,int,long

3.        (*p).foo 等价于p->佛哦;

4.        Sizeof是个操作符!

5.        都好表达时的结果是最右边的表达式值。

6.        优先级相同则从左向右。

7.         

8.        Int* pi=new int; 在堆上分配一个整形,返回对象地址,用地址初始化pi

9.        Int* pi=0;  delete pi;(RIGHT)

10.    Delete pi;  pi保存之前的地址,该地址的对象已不存在。在后面应该加  pi=0;

11.    Delete释放的内存空间还给堆上。“内存泄漏”:删除动态内存失败。

12.    做操作数类型占主导地位:类型隐式转向左边。

13.    隐式类型转换;1.混合类型被转为相同类型。Double aval;  int  Ival; ival转为dval;2.条件表达式if(ival) ;ival转为bool; 3.初始化时,int ival=3.12;3.14转为int类型的 3.

14.    操作数以某种次序转向最宽方向。

15.    算术转换:1.操作数转换为表达式中最大类型。2.右转为左类型(主导)如,3.14159L+’a’;---->’a’--->97(int)-à97.00000(UL)

16.    其他隐式转换:int ia[10];int* ip=ia;ia转为指向第一个元素的指针。任何指针都可以转为void*  类型。0 可以转为任何指针类型。

17.    在条件表达式中定义的变量必须初始化,while(inti=getchar()) ;

18.    Else被匹配给最后一个(最近)出现的还未匹配的if.

19.    找到匹配的case后,之行case后面的句子(如果未写break,则之行下一个case语句知道五年或遇到者break;)直到结束或者break;无匹配则执行switch之后的语句。

20.    Switch内定义变量只能在最后的case或者default中定义。(否则之前的case不能使用未定义的变量)

21.    Do—while中使用的变量要在do之前定义。

22.    Break用于结束最近的while,do  while,for,switch语句。并且执行终止之后的语句。

23.    Continue使最近的循环语句的当次迭代提前结束,只用于while,do  while,for

24.    抛出异常时,先搜索抛出异常的函数,没找到就终止函数,在调用函数出查找,找不到就终止。

25.    Assert用于检查不可能的条件。(表达式为false)输出信息,并且终止程序。(表达式为true)不做任何事。

26.    使用预处理调试 #ifndef NDEBUG 先定义#include NDEBUG

                                      cerr<<”strart main”<<endl;

                                     #endif

则可删除此条始语句,跳过了“#indef ------- #endif”。如果NDEBUG定义了,程序执行时就跳过“#indef ------- #endif”之间的代码(程序所包含的代码仅在开发中执行);

27.    “  ()  “ 函数调用操作符     gcd(c,d) 操作数:函数,参数(如果有参数的话). 操作符括号:()

28.    函数之执行到return时,调用结束被刮器的主调函数恢复执行。

 

                                                                                 C++Primer》阅读笔记续

1.      可以将只想const对象的指针初始化为只想非const对象,//void use(const  int*  p){}; 可以传int*  类型,也可以传const  int* 类型。但不可以将指向非const对象的指针指向const对象//voidreset(int  *ip){} 可以传实参:int* p;不能传const int*p;(不可以修改的(const )不能传给可以修改的)。

2.      不适合用复制实参的情况:1.当需要在函数中修改函数的值2.当需要大型对象需要作为实参传递时(时间/空间消耗大)3.没有办法实现对象的复制。三种情况下将参数改为引用(推荐)或指针。

3.      引用形参直接关联到其所绑定的对象,而不是这些对象的副本。(引用只是别名)

4.      使用引用参数返回额外信息it=find_val(ivec.begin(),ivec.end(),42,ctr); it:函数返回的42第一次出现的位置ctr:42出现的次数//一举两得

5.      非const引用形参必须使用完全相同的类型的非const对象关联。应该将不修改实参的形参定义为const.

6.      Int *&a;从右向左看,首先,a是一个引用,* 代表他是一个指针的引用。修改后,指针的值也会改变(非指传递)

7.      数组两个特性:1.不能复制数组2.使用数组名是,数组名会自动转换为指向第一个元素的指针。

8.      Void  pV(int *)等价于void  pV(int [])等价于voidpV(int  [10]);形参类型都是int *;

9.      &  I;等价于int  *I;

10.  Void pV(const  int ia[10]); //忽略数组形参长度 int i[2];  int  j; pV(j); pV(i); //RIGHT! 

11.  非引用类型数组形参初始化为实参的副本,实参是指向第一个元素的指针,形参复制的是这个值,而不是数组元素本身,操作副本不修改指针的值,可以修改所指对象的值。P208

12.  数组引用:数组的别名。实参与形参大小相同。不传指针传数组本身。

13.  确保函数操作不超过数组边界 1.放一个标记检测数组的结束。(C风格的字符串)2.传递指向数组第一个元素和最后一个元素下一个位置的指针。P2093.将第二个形参定义为表示数组的大小。

14.  包含可变参数(类型/数目)的函数:void  foo(…);

15.  Return :结束当前正在执行的函数,将控制权交给主调函数。

16.  包含有return 的循环后面必须加return

17.  再求return表达式时,需要存储结果,编译器就会创建一个无名的临时对象

18.  钱啊为你不要返回局部对象的引用(函数执行完成时,局部对象的存储空间将会被释放)

19.  函数(与变量一样)可以申明多次,但是只能定义一次。一般:头文件中申明,原文件中定义。

20.  有一个形参由默认参数,后面的形参也必须有默认参数。

21.  内联函数:在程序每个调用点上“内联“的被展开。节约时间。但是只使用于优化的/短小的函数。Cout<<sfun(s1,s2)<<endl; 编译器展开为 cout<<s.size()>s2.size()?s1:s2//sfun(s1,s2)的定义<<endl;  P222

22.  内联函数在头文件中定义。

23.  编译器隐式的将类内定义的成员函数当作内联函数。

24.  每个函数有额外的隐含的形参this。在调用函成员数时,形参this初始化为调用函数的对象的地址。每个函数有额外的隐含的形参将给成员函数与调用该函数的对象捆绑在一起。P224

25.  如果没有显示的构造函数,则编译器会生成默认构造函数。

26.  重载函数:出现在相同作用域中的两个函数。名字相同,形参表不同。之后返回类型不同是不行的。//无法确定调用的是哪个函数

27.  形参予const形参等价的情况仅适用于非引用形参

28.  不要再局部函数内部申明哈书,局部会屏蔽全局函数。C++中名字查找发生在类型检查之前。P231

29.  只有形参是引用或者置指针时,形参是否为const才有影响。

30.  在引用函数名单没有调用时,函数名将被自动的解释为指向函数的指针。P237用函数名与在函数名前加上  &  等效。通过指针调用函数 (*pi)(“hello”,”world”);或者不用解引用 * pi(“hello”,”world”);

31.  Int (*ff(int))(int  *,int);从申明的名字开始由里向外理解。Ff(int)ff申明为一个函数,并且有一个int型的形参。函数返回  int (*)(int *,int) :是一个指向函数(有int*,int 两个参数)的指针。或用 typedef  :  typedef int(*PF)(int *,int);  PF  ff(int);//与前面的写法等效  PF:函数返回类型

                                                                                        C++Primer》阅读笔记再续

1.(P378)当函数返回类型为类引用时,可以连续写调用的函数。如:  
 Screen& move(index r,index c);
 Screen& set(char);
 Screen& set(index,index,char);

int main()
{
 Screen  S;
 S.move(4,0).set('#');//将操作序列连成一个表达式
}

2.在c++的类中, 如果一个函数被const 修饰,那么它将无法修改其成员变量的,但是如果这个成员变量是被mutable修饰的话,则可以修改。即可以修改类内被mutable修改的变来那个(不管是私有的还是const的。即使函数是const型的)。

3.名字必须在使用之前进行定义(或申明)。一旦一个名字被作为类型名,就不能杯重复定义。
4.名字查找,函数内部----类内====--函数定义之前的作用于众找
5.new的三个动作:1.分配空间2.初始化3.返回对象的值
6.不管对象是否为const都用构造函数初始化。const或者引用类型数据成员只能在初始化列表中初始化
7.谨慎使用构造函数初始化表
8.成员被初始化的次序就是成员被定义的次序
class {int i;int j;public:  X(int val):j(val),i(j){}};//错误!i先定义,i先被初始化,就是用未知的j初始化了i !错误!
9.如果可以,使用默认实参!
10.类只要定义了一个构造函数,编译器就不回生成默认构造函数。一旦定义了构造函数就必须显示定义默认构造函数!
11.当对象定义在局部作用域时,内置(int/double/char...)或者符合类型的成员不进行初始化。
12.Sales  obj();//错误,obj是一个返回Sales类型那个的函数不是对象
   Sales  obj=Sales();//用好Sales的构造函数初始化对象obj;
13.隐式类类型转换:
private:
 std::string consents;
 index cursor;
 index height,width;
 const int a;
public:
 Screen():a(0){}
 Screen(int b):a(b){}
 void test(Screen s)
 {cout<<"dui!";};

int main()
{
 Screen  S;
 S.test(4);//Screen(int b):a(b){} 编译器接受一个有int型形参的构造函数生成一个新的对象作为实参。新生成(临时的)的对象传递给test函数。但是,一旦test函数结束了对象就不存在了。
//explicit用于抑制有构造函数定义的隐式转换,子啊类内定义构造函数式加上explicit就不会存在隐式转换。在类外定义是不用加explicit!

13.任何构造函数都可以显示的创建临时对象。如上例,显示调用构造函数: S.test(Screen(4));也可以!    P395
14.友元机:允许一个类将对其非公有成员的访问权授予制定的的函数或类。使用friend定义。他只能出现在类定义的内部。友元类的函数可以访问授予他友元关系的类的非公有成员。
15.static数据成员独立于该类的任意对象而存在。每个每个static数据成员(变量)与类关联,不与对像相关联。static成员函数没有this指针,可以直接访问所属类的static成员,但是不能直接使用非static成员。static变量不计到对象的大小,是该类所有成员共享的。只能通过域作用符直接调用static成员或者对象、引用、指向该类型的指针间接引用。类的成员函数可以不用域作用符。static函数
定义时不用写static。static函数不能申明为const,//const函数,不能修改该函数所属对象。也不能申明为虚函数。
16.static不是通过构造函数初始化,而是在定义时进行初始化。
17.static数据成员可以是该类成员所属的类类型。非staic成员被限定只能神明为其自身的指针或引用。class  Screen
{
public:
 friend Win;
 typedef std::string::size_type index;
private:
 Screen  *S;//ok
        Screen   S;//不  Ok

2012/02/24
18.不能在类内定义数据;因为定义要分配空间,而类型定义不需要分配空间。
19 P406.不管类是否定义析构函数,编译器都会自动执行类中非static数据成员的析构函数
20.复制的构造函数、复制操作符、析构函数总称为:复制控制。不写时编译器会自动生成。
21.string  null="test";//编译器首先调用接受一个C风格的字符形参的string构造函数,创建一个临时对象,在使用string的复制构造函数将null初始化为临时对象的副本。
22.以非引用类型做返回值时,返回return后埔值的副本。
23.为了防止复制,类必须显示申明其复制构造函数为private!就不可以复制类的对象!弱国只是申明为private(复制构造函数)则连友元和成员都不可以复制。
24.写复制构造函数时一般要把重载赋值操作符
25.Sales  *p=new  Sales;{Sales item(*p); delete p;}item在超出作用域时会自动撤销,所以遇到右边或括号时,就回运行item的析构函数。对台分配的对象只有在只有当该对象的指针被删除时才会撤销,否则,对象一直存在,会造成内存泄漏。而且,对象内部的资源也不会释放。对象的引用或者指针超出作用域时,不会运行析构函数。只有删除该指针或者对象超出作用域是才会运行析构函数。
26.撤销容器或者数组时,数组中的元素按照逆序(成员在类中申明的次序的逆序)撤销,最后撤销下表为0的元素。
27.三法则:析构函数,复制构造函数,复制操作符三个应该同时出现。有其中一个就有两外两个
28.析构函数不可以重载,应用于类的所有对象。
29.编译器会生成合成析构函数。在用户编写的析构函数之后执行。
30.P419 管理指针三法
31.悬垂指针:指向一个不服存在的对象。
32.P425管理有指针成员的类必须有复制构造函数,赋值操作符,析构函数。
33.管理有指针成员的类的来年各种方法:1.定义智能指针(P421)2.定义值类型(P426 使指针表现的像一个值。复制构造函数:会重新分配一个int类型对象,再将该对象初始化被复制对象的值。 复制指针所指向的对象,而不是指针本身。)
34.重载操作符必须就具有一个类类型或枚举类型的操作数。
35.一般将算术和关系操作符定义为非成员函数,而将赋值操作符定义为成员。当操作符为成员函数时有this指针,并且指向左操作数。
36.尽量不要重载逗号,取地址符,逻辑或逻辑与操作符。重载后就不能用原来的内置含义。
37.P435 选择成员或者非成员实现!?
28.一般而言,输出操作符(定义为非成员)应该输出对象的内容,进行最小限度的格式化,不应该出书换行符。
29.输入操作符必须处理错误和文件结束的可能性。
30.设计输入操作符时,如果可能,要确定错误回复措施,这很重要。
31.未解决两个函数形参树木和类型相同,可以在期中一个函数的定义中添加一个无用的形参!
32.定义调用操作符,即括号:“()”的类,其对象成为函数对象。他们是行为类似函数的对象(就像函数一样调用对象)
33.直接调用构造函数会产生类的临时对象。
34.转换操作符("operator  int()"):给定类类型的对象,该操作符将产生其它类型的对象35.通用形式:operator type();//type:内置类型,类类型。
36.转化函数必须是成员函数,不能指定返回类型,并且形参表必须为空。但是必须显示返回一个制定类型的值。转换函数一般不应该改变转换的对象,因此转换操作符一般定义为const。
37.类类型之后不能再跟一个类类型转换。//A转到B,B转到C 错!


第四部分:
P472  15章 面向对象编程
1.面向对象编程基于三个基本对象:数据抽象,继承,动态绑定!关键思想:多态性。许多情况下可以互换的使用派生类或基类的多种形态。
2.基类希望派生类重新定义的定义为虚函数。不希望重新定义的,只是希望派生类继承的不能定义为虚函数//会被子类定义的同名函数覆盖
3.通过基类的引用或者指针调用函数,发生动态绑定。引用或者指针既可以指向基类也可以指向派生类对象。用引用或者指针调用的虚函数在运行时确定,被调用的函数是引用或者指针所指对象的实际类型所定义。
4.除了构造函数任意非static函数都可以是虚函数。需要派生类重定义的都要定义为虚函数。
5.private成员只能由类的成员和友元访问。派生类也是:可以访问public,不能访问private
6.protected像是public和private的结合。像private一样,protected不能被类的用户访问,只能通过类内定义的函数访问(就是基类对性爱那个不能访问基类的protected)。像public一样,protected成员可以被该类的派生类访问(不能直接访问)。派生类只能通过派生类的对象访问基类的protected成员。
7.只有类本身和友元可以访问类的private部分。派生类不能访问。提供给派生类型的接口是protected和public成员的组合。
8.P477 派生类中虚函数的申明必须与基类中定义的完全相同,有一个例外:返回对基类指针(引用)的虚函数,派生类的虚函数可以返回积累函数返回类型的派生类的引用、指针。
9.一旦在基类申明为虚函数,就一直是虚函数,派生类无法改变,派生类重定义时,可加可不加virtual。
10.C++默认函数类型为整形(char,long,double,int)。
11.基类必须是一已定义的类。
只申明没有定义对的不可以做基类。所以,不能从自己派生出一个类。因为派生类必须知道基类的数据成员是什么,以及访问权限。
12.只有通过指针或者引用调用是=时才在运行时决定确定对象的动态类型。
13.编译是确定非virtual调用,非virtual的book函数, ZSF(sife& a){cout<<"A:"<<a.a<<endl;a.book();};传入子类 的对象也会调用基类的book函数,及时子类中重定义了book、自己的版本。
14.P484 接口继承:public继承。实现继承:protected,privacted.
15.修改基类中是public在private标记继承后在派生类中的private的访问权限:
#include <stdio.h>
#include <iostream>

using namespace std;

class Base
{
public:
 int size() const {return i;}
protected:
 int i;
};

class Derived:private Base
{
public:
 using Base::size;
protected:
 using Base::i;
};

main()
{
}

16.默认访问级别:class是private,而struct是public(即不知定时默认的访问级别)。
17.友元可以访问private和procected,友元不能继承。
18.如果基类定义static成员,无论派生出多少类,整个集成层次中只有一个这样的成员,每个static成员只有一个实例。如果在基类中是private,则派生类不能访问!
19.派生类含有基类的数据,所以在基类上的操作在派上类上也可,所以存在派生类对象引用到基类对象引用的转化。(派生类对象地址可以赋给基类指针,用派生类初始化基类!)指针也类似。
20.基类默认构造函数执行顺序,隐式调用基类构造函数初始化基类数据,执行完后,执行派生类的默认构造函数,初始化派生类的数据。(构造:盖房子。析构:拆房子)
21.一个类只能初始化自己的直接基类。
22.重构:重新动议类层次,将操作或数据从一个类转移到另一个类。
23.要保证运行适当的析构函数,基类中的析构函数必须是虚函数。当通过指针调用是运行那个析构函数因指针所指对象的不同而不同。基类析构函数是是虚函数,派生类中也是,根类应该无论如何写一个徐析构函数。
24.在基类构造函数或者析构函数中,将派生类对象当作基类对象使用。
25.派生类重载了成员,通过派生类型只能访问派生类中定义的成员。
26.有一个或者几个纯虚函数的类叫抽象类,抽象类不能创建对象。
27.容器中存有基类的对象,如果再存入派生类的对象则只存积累的数据,派生类的数据杯切掉。
28.动态绑定:通过基类的指针或引用调用虚函数时发生动态绑定。用引用调用的虚函数在运行时决定。基类的虚函数可不再子类中重定义。虚函数P472
29.P504 指针存储的最简单策略 , 将指针存入对象中当对象被析构指针自动被delete
句柄类存储和管理基类指针、

16章
P526
1.template<typename/class  T>int comapare(){}T表示那个类型由编译器根据所用的等函数确定。模板形参表不能为空
2.内联木板函数:template <typename T>inline T min(const T&,const T&);
3.模板类定义:template<class Type>class Queue{};
4.模板形参的名字可以在申明为模板形参之后知道模板申明或者定义的末尾处使用。
5.与全局作用于中对象昂、变来那个名字相同时,木板会屏蔽全局名字。且被申明为木板后不能在木板累重用:template<class T>T calc(const &T){typedef double T;//ERROR!}
6.模板申明:母本可以只申明不定义,申明必须指出函数或者类是一个模板:
template<class T>int comparer(const T&);
7.编写模板代码时对实参类型要求尽可能少。模板形参是const引用。函数中的测试只用<比较。
8.参数是引用时,数组不能转换为指针。
9.调用模板函数或者类时需要知道函数定义。将目标那函数、类定义在原文件中。
10.包含编议模型:编译器必须看到所有模板的定义。
头文件:
#ifdef INCLUDE_H
#define INCLUDE_H
template<class T>int compare(const T&,const T&);
#include "include.cpp"
#endif
源文件:
#include <stdio.h>
#include "include.h"
template <class T>intcompare(const T& v1,const T& v2)
{
 if(v1<v2) return -1;
 if(v2<v1) return 1;
 else
  return 0;
}
main()
{}
2.分别编译模型:编一起回味我们跟踪相关的模板定义。exprot关键字:指明给定的定义可能会在需要其他文件中实例化。申明时不写,定义时在template之前加export.如果在头文件中使用export则该头文件只能被一个原文件使用。
P544
11.类模板成员函数的定义必须一template开头,后接模板形参表。必须指出是那个类的成员。类名必须包含其模板形参。类模板成员函数本身也是成员函数。类模板成员函数的模板形参由调用函数对象的类型决定。
12.当定义非类型辛灿的模板对性象时,必须为每个形参提供常量表达式:template<int hi,int wid>class Screen{}; Screen<24,48> Hp;且参数必须是编译时常量。
13.模版特化:template <> int comp<const char*>(const char* &v1,const char* &v2){}
14.类特化版本:template<>class Queue<const char*>{};
外部定义类成员:void Queue<const char*>::push(const char* val)
{}//之前不加template<>
15.特化申明:template<> void Queue<const char*>::push(const char* const&);//放在头文件中
16.部分特化:template <class T1,class T2>
             class some_template{};
             template<class T1>
              class some_template<T1,int>{};//T2 为int即特化int P570
17.函数模板可以重载。普通函数优先于木板版本。
18.C风格字符串:char *!char型指针指向的 一串!
19.定义模板特化比非木板版本好。

第十七章
1.异常处理:完成错误检查和错误处理,且错误处理必须括约独立开发的多个子系统。问题
监测与问题处理是分离的。
  命名空间:能够用各种库构造程序。
  多重继承:能够处理更复杂的应用概念。
2.执行throw时候,不执行throw之后的语句,而是将控制从throw转移到匹配的catch。沿着调用连的函数提前退出。处理异常时,抛出异常的块中的局部存储不存在了。释放时会执行构造函数,不撤销内置类型对象那个。new动态分配的不会撤销。栈对象(局部)会撤销。异常对象:由throw创建,被初始化累可以被复制的类型。不要跑出局部对象。尽量不要抛出指针。
3.当抛出一个表达式时,被抛出对象的静态编译时类型将决定异常对象的类型。
4.当catch结束时候,在紧接在于该try块相关的最后一个catch自居之后的点继续执行。栈展开:P582
5.cathch()的表达式中必须是确定的类型。前向申明不行。
6.从新抛出:throw;
7.捕获所有异常:catch(...){throw};//与其他catch语句一起用,他必须是最后一个。
8.异常安全:及时发生异常,程序也能正确操作。:如果发生异常,被分配的任何资源都适当的释放。
9.RAII(资源分配即初始化):定义一个类Resourse来封装资源的分配和释放,保证正确释放资源。要分配资源就定义该类Resourse类行的对象,如果不发生异常就在对象超出作用域时执行析构函数,如果有异常,编译器就将运行Resourse的
析构函数作为异常处理的一部分。
10.quto只能用于管理new返回的对象。不能将auto_prt放在标准容器中。void fun(){auto_ptr<int> ap(new int(42));}//因为构造函数是不能被隐式转换的,所欲i,必须使用直接初始化。不能用“=”复制初始化。有异常但是还未到对象结束之前会析构他。auto_ptr对象复制或赋值要谨慎。auto_ptr是模板,要将他绑定到指针。对未绑定的指针解引用是没有作用的。
11.异常说明:void recoup(int) throw (runtime_error);recoup接受一个int值的函数,返回void。如果recoup抛出一个异常,该一场将是runtime_error对象或者是由runtime_erroe派生的累i系那个的异常。void no_problem() throw();//保证不跑出异常。跟在const之后int test ()const throw();派生类不能再异常列表中增加异
常。
命名空间 P599
12.namespace作用域不能以分号结束。不同命名空间有相同作用域。命名空间内部可以直接访问成员,外部必须知道哪个那个命名空间。一个namespace就是一个作用域。
13.namespace应用举例: sales.h:namespace cap{class sales{};} //query.h namespace cap{class Query{};} .CPP:#include "sales.h" namespace cap{class sales{}} #iclude "query.h"namespace cap{class query{}}
14.命名空间别名:namespace primer=cplus_primer;//cplus_primer之前存在的命名空间,可以有多个别名
15.不能用using申明来引用特定函数。using指示将命名空间成员提升到外围作用域(全局作用域)
//P614多重继承
16.隐士访问级别!??
17.基类之间没有隐含关系
18.基类的析构函数都定义为虚函数。西沟顺序与构造顺序相反(拆房子)
19.虚继承是一种机制:类通过虚继承指出他希望共享其虚基类的状态。(解决重复继承)
20.由最底层的派生类的构造函数构造虚基类。如果不显示构造虚基类,就调用虚基类的构造函数。无论徐积累出现子啊什么地方,总是先构造虚基类在构造非徐基类(不管继承次序)。


//18章
1.new三个动作:调用operaror new的标准库函数,分配空间。2.运行构造函数3.返回新分配并且构造的对象指针。
delete:对所指对象运行析构函数。调用operator delete标准库函数释放该对象所内存。
2.new/delete的重载版本:void *operator new[] (size_t);//申请数组delete[] (void*);//释放数组
3.operator delete函数不运行析构函数。
4.运行时类型识别:RTTI
5.typeid操作符:将积累转换为派生类指针、引用。type_info类:比较对象是否相等。P653
6.类成员的指针:class Screen{std::string conents;}; string Screen::*;//指向std::string类型的Screen类成员的指针。
7.嵌套类:最常用于定义执行类。P658
8.联合:union不能具有静态成员,引用,有构造函数、析构函数,赋值操作符的对象!默认像是struct,默认为public。union可以定义成员函数(构造、析构)。不能作为基类。常用语switch判断中(P664)
9.局部类:函数体内部定义的类(即定义一种类型,该;类只在局部可见,且不能使用定义该类的函数中的变量)。局部类可以将外围设为友元遗提供访问。通常局部类的所有成员为public。
10.固有的不可移植的特征:1.位域:一种特殊的类数据成员,保存特定的位数,需要将二进制数据传递给另一程序或硬件设备的时候,通常用位域。位域在内存中的布局时及机器关的。inta:8;//a是八位的。 Bit mode: 2;//mode有两个位。最好将位域设为unsigned int比如(typedef unsigned int Bit;)
11.位域不能使用&,不能有引用类位域的指针。位域也不能是类的静态成员。
  unsigned int st: 3;st=100;//st=4;
12.volatile:volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。可以用编译器的控制或检测之外的方式改变对象的值。对这样的对象不应该执行优化!volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.简单地说就是防止编译器对代码进行优化.volatil对象只能调用volatile对象成员函数。
volatile int disp;象const一样,只能将volatile对象的地址赋给volatile的指针。通过将形参定为Foo(const volatile Foo&),可以从任何种类的FOO对象进行复制或赋值。普通Foo,const Foo,volatile Foo,const volatile Foo。volatile确切含义与机器相关。
13. 连接指示:指出任何非C++函数所用的语言。 extern "C" size_t strlen(const char *);//申明此函数为C语言所写。第二种写法:extern "C" {int strcpy(const char*,const char* );char *strcat(char*,const char*);}头文件也可以这样申明:extern "C"{#include <string.h>//...}//头文件中函数都是C语言写的。可以嵌套使用。
14.extern "C" double calc(double dparm){...}//此函数可以被C语言调用。支持什么语言岁编译器而定!被extern "C"修饰的变量和函数是按照C语言方式编译和连接的!
15.不能将C函数指针初始化为C++函数指针(反之亦然)
16.extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。另外,extern也可用来进行链接指定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值