Cpp学习笔记

时间:2016-11-11                from:<C++面向对象程序设计>-谭浩强

第一章.   C++的初步知识

1.    cin>>和cout<<是输入、输出流对象,使用时要包含头文件<iostream>,其中cin>>a>>b而不能是cin>>a,b(cout也是)

2.    类由数据和函数组成,C++中通常将数据定义为private,只能供类的函数调用不能类外调用。而将类的函数定义为plublic,可以在类外调用函数

3.    假设有一个类Student,定义对象(类变量)的方法是:Student  stu1,stu2;其中Student不占存储空间,而对象stu1和stu2则占存储空间

4.    如果C++程序使用系统提供的头文件而不想带.h时,必须使用命名空间:using namespacestd;

5.    C语言中不允许有同名的函数出现;C++中允许有同名的函数出现,但是参数的类型或者个数必须有一样不同系统才能识别函数是不同的

6.    int a=2,b=3,c=4,d;这样子定义是可以的

7.    C++中函数模板的定义:template<typenameT1,typename T2,…>或者

template<classT1,class T2,…>,后面就是以T1,T2为类型定义的模板函数。其中class和typename是一样的,这里的class不是类的意思

8.    模板函数适合于函数功能相同且参数个数相同而类型不同的一类函数,简化设计避免重复定义

9.    C++在函数定义时允许形参有默认的值,不过有默认值的形参必须放在形参表的最右边,否则报错。如果要使用默认值的形参,函数调用时可以不用传递实参,少写一两个实参

10. “引用”是C++对C的一个重要扩充,int a;int&b=a;其中b就是对a的引用,a和b代表同一个变量。b作为a的引用后,不能再作为其他变量的引用

11. 其实C++中很少使用独立变量的引用,要用变量直接使用它的原名,“引用”主要作为函数参数来使用,eg:void swap(int&a,int &b)—swap(i,j)将引用作为形参,将变量名作为实参传递给引用,实际上还是地址传递,但是比指针更加容易理解和操作,减少出错的机会

12. 对引用的进一步深入:

(1)  没有void型引用(因为没有void型变量,但是有void型指针)

(2)  不能建立对数组的引用,eg:char c[6]=”hello”;其中c只代表数组首元素的地址,并不是一个有存储空间的变量

(3)  可以建立对指针的引用,int i=5;int *p=&i;int * &pt=p;其中pt是指针p的引用

(4)  可以用const对引用加以限定,eg:int a=3;const int &b=a;这对于引用作为形参的时候,要保护函数的形参不被改变很有用

(5)  引用还可以这样子,int i=5;const &a=i+3;àinttemp=i+3;const int &a=temp;(其中temp是临时变量,a是临时变量的引用)

13. inline(内置函数)和#define的区别:inline是在编译时将代码嵌入主调函数中,而#define是在编译前将代码进行替换且不检查语法错误。inline适合代码量小且频繁使用的函数

14. C++可以用”::”表示全局变量,因为在局部变量和全局变量名相同且局部变量会覆盖全局变量.eg:cout<<a;cout<<::a;

15. C++提供string类型(<string>中),string字符串变量后面不跟’\0’,string类型的字符串数组eg:stringstr[3]={“abcd”,”ef”,”efg”};其中str[0]([1],[2])存放的是指针而不是字符串

16. C语言中malloc函数只能从用户处知道要开辟的内存的大小而不知道数据的类型,因此无法使其返回的指针指向具体的数据。其返回值一律为void *类型,必须在程序中进行强制类型转换,才能使其返回的指针指向具体的数据

17. C++使用new申请内存,eg:char *p=new char[10];(new申请一个指向char有10个字节的指针)。另外delete p;表示释放指针p指向的内存,delete []p;表示释放p数组的内存

18. 注释符”//”是C++特有的,”/**/”才是C的默认注释符

 

 

第二章.类和对象的特性

1.C++中的继承重用是一个重点,也是我的弱项,用的好可以极大提高代码质量。类的多样性:对于继承同一个父类的多个类,他们对于同一个消息的反应千差万别

2.程序=对象N+消息设计过程:OOA->OOD->OOP->OOT->OOSM

面向对象分析->面向对象设计->面向对象编程->面向对象测试->面向对象维护

3.C++通常将类的方法定义为public(当然你也可以将方法定义为private,只供内部的方法调用),将类中的数据定义为private,如果private成员想被子类继承还可以定义为protected

4.C++中用一个类实例化多个对象后,这些对象的数据分开存储而方法因为都是相同的所以只需要存储一份,那么当一个对象调用它的方法时怎么知道是调用哪个对象的数据呢?当用该对象调用方法时,就用this指针指向该对象,this指针的值是被调用的成员函数所在的对象的起始地址,this指针是隐式使用的,它是作为隐式参数传递给成员函数的

5.可以定义一个类的指针来指向该类的对象,也可以使用引用来访问对象

6.C++的实际编程中,将多个类的声明放在一起形成.h文件,将类的成员函数实现放在一起形成.cpp文件。其中多个类的声明形成的.h文件就是我们程序的  ”类库”,在主文件中(通常是main.cpp),将类库的.h文件include进来而不用将类的函数实现.cpp#include进来(这就实现了信息的隐藏,因为你看不到.cpp源文件),我们就可以使用这些类了---接口和实现的分离思想

7.开发商向客户提供类库和类成员函数实现细节.cpp编译后的目标文件,实现了信息的隐藏,保护了自身的权益


 

第三章.怎么样使用类和对象

1.C++用构造函数对类的数据进行初始化,类的构造函数没有返回值但是可以带形参,是在建立对象时自动调用构造函数并且可以传递实参。构造函数内除了对类的数据进行初始化外不应该有其他操作(我记得之前用QT做一个系统时将对象所有的函数的调用都写在构造函数里了,这样很不好!!!),保证程序的清晰性

2.重载:至今遇到了函数的重载(同名函数的不同表现形式)、构造函数的重载(一个类中可以有多个构造函数,但是只有一个起作用)。重载的意思应该是对同一个事物有不同的表现形式

3.静态局部变量在函数调用结束时变量并不释放,只在main函数结束或调用exit函数结束程序时才释放

4.析构函数在对象释放时自动调用,在同一个作用域中,先调用的对象后析构,析构函数没有返回值,没有函数类型,没有参数

5.定义一个指向类的成员函数的指针:void (Time::*p2)();使p2指向成员函数的形式:p2=&Time::fun; 

6.C++可以用new来建立动态对象,eg:Box *pt=newBox(12,15,12);(如果构造函数没有参数new时可以不用带参数)

7.C++中可以将一个对象赋值给另一个对象eg:Box box1,box2;box1=box2;同时也可以将一个对象复制到另一个对象:Box box1=box2;  类可以作为函数的返回值,因为返回值是类的对象

8.C++中尽量不要调用全局变量,因为 容易导致出错。C++类中的静态数据和静态成员函数都是属于类而不是属于对象的(主要用于同一类的多个对象之间数据共享),静态函数和静态数据成对出现,使用时用  类名::(静态数据或函数)----同一个类的对象之间信息共享的方法 

9. 友元函数:假设有一个类Time里有一个函数void display(Date&) ;在另一个类Date中将display()声明为该类的友元函数friend voidTime::display(Date &);那么Time里的display函数就可以使用Date里的数据了—不同类的对象之间信息共享的方法 

10.友元类:在类A的定义中friend B;就是将类B作为类A的友元类,这时类B的所有函数都可以访问类A的成员。但是Friend是单向的,类A的函数不能访问类B的成员(在实际工作中,除非有必要,不然一般并不把这个类声明为友元类,而只是将有需要的函数声明为友元函数,这样更安全一些

11.C++除了提供函数模板外,还有类模板。模板的作用是为了功能相同而类型不同(参数类型,返回值类型等)的提供

 

  

第四章.对运算符进行重载

1. 重载运算符的方法是定义一个重载运算符的函数,重载运算符的函数的一般格式如下:函数类型operator 运算符名称 (参数表){对运算符的重载处理}

2.重载运算符的规则:(1)不能自己定义新的运算符,只能重载C++已有的运算符(2)不能有默认的参数,否则就改变了运算符参数的个数(3)重载运算符的参数必须至少有一个是类对象

3.将运算符重载函数作为类的成员函数和友元函数的区别:作为类的成员函数,必须建立在表达式左边的操作数是类的对象的基础上(假设有复数类对象c1+c2,那么系统会把它解释为c1.operator+(c2)),即左边的操作数会作为类对象去调用成员函数operator+。而作为友元函数则没有这方面的限制,所以通常将双目运算符重载为友元函数,而单目运算符重载为成员函数

4.C++中有复制对象构造函数(eg:complex(complex &c);)和转换构造函数(eg:complex (doubler){real=r;image=0;}),转换构造函数用于将C++中标准类型转换成类对象且只能有一个标准类型的形参,转换过程:complex c1;c1=complex(3.5);(comlex(3.5)会生成一个无名对象赋值给c1)。C++也可以将一个类对象转换成另一个类对象,与上面的类似。同样类对象也可以转换成C++的标准类型:operator 类型名(){实现转换的语句}

5. 转换构造函数和运算符重载函数都是隐式调用的,eg:c2=c1+3.4; 

 



第五章.继承与派生

1. C++支持从多个父类中继承(eg:classstudent1:public student—公有继承),称为多继承。但子类不继承父类的构造函数和析构函数且子类中新定义了和父类相同的成员时会覆盖从父类继承的成员        

2.子类继承父类的三种方式:公有继承(父类的私有数据不能继承,其他不变继承)、保护继承(父类私有数据不能继承,其他的在子类中变成保护数据)、私有继承(父类私有数据不能继承,其他在子类中变私有数据)--很好记。从三种继承方式可以看出,父类的私有数据都是不能被子类继承的,那我们在子类中应该怎么访问父类的私有数据呢?答案是通过子类从父类继承的成员函数访问父类的私有成员

3.类B是类A的派生类,类C是类B的派生类,那么类C也是类A的派生类

4.因为派生类继承了基类数据成员,而又无法继承基类的构造函数,所有在派生类的构造函数中调用基类的构造函数,派生类的构造函数一般形式:派生类构造函数名(总参数表):基类构造函数名(参数表){派生类数据的初始化},其中基类的参数表中不包含参数类型,总参数表包含基类的参数表,eg:man(char sex,int age,int height,intwidth):people(sex){…}

5.在类中定义其他类的对象称为子对象,这种方式成为类的组合,对子对象的初始化应该是在该类的构造函数中而不是声明处。形式:派生类构造函数名(总参数表):基类构造函数名(参数表),子对象名(参数表){派生类对象的初始化},总参数表的形参名必须不同,系统按照参数名来传递参数 ,调用顺序:基类构造函数->子对象构造函数->派生类构造函数

6.派生类调用析构函数时,会先调用自身的析构函数,然后调用子对象的析构函数,最后调用基类的析构函数

7.多重继承多个类,而这些类中有同名同类型的数据成员(这些同名同类型的数据成员或者函数在派生类中是覆盖而不是重载),那么派生类可以通过:派生类对象.基类类名::成员的形式来表示

8.类A是类B和类C的基类(那么类B和类C中都有一份类A的拷贝),类B和类C是类D的基类(那么类D就有两份类A的拷贝了),事实上我们不需要重复的拷贝,所有可以将类A声明为类B和类C的虚基类格式:class 派生类:virtual  继承方式  基类名。那么类D的构造函数需要对虚基类A,基类B和C的构造函数进行初始化

9.基类和派生类之间可以互相转化,eg:基类的指针可以指向派生类,但是只能访问派生类中属于基类的部分,新增加的部分不能访问

 

 


第六章.多态性和虚函数

1.静态多态性:函数重载和运算符重载,发生在编译时,速度快。动态多态性:由虚函数实现,由程序运行时确定

2.虚函数:基类声明是虚拟函数是虚拟的,并不是实际存在的函数,然后在派生类中才正式定义此函数

3. 如果将基类的函数命名为虚函数,那么它的派生类中就可以重载这个虚函数,用基类指针对象派生类对象后,在用该指针调用该虚函数就可以调用派生类重载后的虚函数

4. 如果基类和多个派生类中有同名同类型的函数(完全相同的函数但功能不同),如果指针是基类指针且指向了派生类对象,那么通过基类指针调用派生类对象时只能调用基类有的那些成员—系统进行了自动指针类型转换。所以在基类中可以使用虚函数(函数定义前加virtual)定义该函数,然后在各个派生类中重新实现该同名函数,指向各个对象的基类指针就可以用pt->函数的形式调用该同名函数,实现函数的重载---这就是通过虚函数实现的多态性

5.虚函数的作用就是给继承的类进行重载的,当然也可以选择不重载

6.当一个类带有虚函数时,编译系统会为该类构造一个虚函数表,它是一个指针数组,存放每个虚函数的入口地址

7. 纯虚函数:如果基类的函数只想被派生类定义而本身不实现,那么就可以定义为纯虚函数:virtual 函数类型 函数名(参数表)=0;如果在派生类中不实现纯虚函数,那么纯虚函数在派生类中依然是纯虚函数

8.抽象类相当于java的接口,只要类中至少有一个纯虚函数,那么该类就是抽象类,就不能定义对象,但是可以定义抽象类的指针去指向它的派生类,然后调用派生类的虚函数(重载的同名函数)

 

暂时就先写这么多吧,等以后工作有接触到C++的时候再补充嘿嘿                                                                                                                                                                                                                                                                                                                                                                                                                    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值