C++知识点总结范本模板.docx
- 文档编号:26304230
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:33
- 大小:91.88KB
C++知识点总结范本模板.docx
《C++知识点总结范本模板.docx》由会员分享,可在线阅读,更多相关《C++知识点总结范本模板.docx(33页珍藏版)》请在冰豆网上搜索。
C++知识点总结范本模板
类和对象初步
1.类的定义在定义外成员函数的实现
2.类的成员函数之间可以相互调用,类的成员函数也可以重载,也可设默认参数值
3.一般来讲,一个对象占用的内存空间的大小等于其成员变量的体积之和。
每个对象都有自己的存储空间(成员变量),但成员函数只有一份对象名.成员名指针—>成员名引用名.成员名
4.private:
一个类的私有成员,只能在该类的成员函数中才能访问public:
proteced:
5.class默认privatestruct默认public
6.内联成员函数:
成员函数名前加inline或函数体写在类定义内部的成员函数。
执行更快,但会带来额外的内存开销
构造函数
1.构造函数全局变量在堆上,系统自动初始化为零。
局部变量在栈上,初始值是随机的,需要初始化。
2.构造函数:
对对象进行初始化。
构造函数执行时对象的内存空间已经分配,构造函数的作用是初始化这片空间。
可重载,不写的话有默认构造函数,但是如果编写了构造函数,那默认构造函数不会再执行。
是一类特殊的成员函数。
不写返回值类型,函数名为类名。
3.对象在生成时一定会调用某个构造函数,一旦生成,不再执行构造函数。
4.P183Ctest*pArray[3]={newCtest(4),newCtest(1,2)}
5.复制构造函数:
其是构造函数的一种,只有一个参数,为本类的引用,防止混淆,构造函数不能以本类的对象作为唯一的参数。
默认复制构造函数。
6.复制构造函数被调用的三种情形:
1用一个对象去初始化另一个对象时ComplexC1(C2)ComplexC2=C1;2函数的参数是类A的对象。
形参未必等于实参函数中用对象的引用不会调用复制构造函数voidFunction(constComplex&c)3函数的返回值是类A的对象
7.类型转换构造函数:
除复制构造函数外,只有一个参数的构造函数C=6
8.析构函数:
在对象消亡时调用,可以定义其做善后工作。
是一类特殊的成员函数,一个类有且只有一个构造函数。
默认析构函数
9.注意:
函数的参数对象以及作为函数返回值的对象,在消亡时也会调用析构函数
10.构造函数析构函数变量的生存期:
全局变量在main函数开始执行前初始化。
函数调用结束后静态局部对象不消亡。
main函数结束时,静态局部对象先消亡,全局对象再消亡
11.静态成员变量和静态成员函数:
实质是全局变量和全局函数,被所有的同类共享.生成在对象生成之前。
计算体积时不会将静态成员变量算入其中老师的coeblocksC013静态成员变量必须在类定义外进行声明,声明的同时也可初始化.因为静态成员函数内部不作用于某个对象,所以不能访问非静态成员
12.常量对象和常量成员函数:
常量对象一旦初始化后,值再也不能改变。
常量对象和普通对象都可调用常量成员函数.通过常量对象调用常量成员函数。
常量成员函数内不能调用同类的非常量成员函数,静态成员函数除外。
13.封闭类:
包含成员对象的类.在定义封闭类的构造函数时,用初始化列表的方式初始化.封闭类对象生成时,先执行所有成员对象
友元和this
1.友元函数:
把全局函数和其它类的成员函数声明为友元函数后,可直接在友元函数内部访问该类的私有成员;但不能把其它类的私有成员函数声明为友元.
2.全局函数声明为友元:
friend返回值类型函数名(参数表);
3.其它类的成员函数声明为友元:
friend返回值类型其它类的类名:
:
成员函数名(参数表);
4.友元类:
类A将类B声明为自己的友元,则类B中所有的成员函数都可访问类A对象中的私有成员。
私有成员函数也可访问。
5.注意:
友元关系不能传递。
6.this指针:
非静态成员函数的实际形参比编写的多一个,就是this指针,指向成员函数作用的对象.通过this指针找到对象所在的地址,继而找到对象非静态成员变量的地址。
7.注意:
因为静态成员函数不作用于某个对象,所以在其内部无this指针,不能使用。
运算符重载
1.运算符重载:
是对已有的运算符赋予多重含义,使不同的运算符作用于不同的类型的数据时导致的不同的行为。
实质是编写运算符作为名称的函数.
2.返回值类型operator运算符(形参表){。
.。
。
..}
3.使用了被重载的运算的表达式,会被编译成对运算符函数的调用,实参是运算符的·操作数,运算的结果是函数的返回值。
运算符可多次被重载,可重载为全局函数和成员函数.重载为全局函数时,参数个数等于操作符的个数;重载为成员函数时,参数的个数等于操作数的个数减1.a—b被重载为a.operator—(b);
4.类名(构造函数参数表)这个写法表示生成一个临时对象。
该临时对象没有名字,生存期到包含它的语句执行完为止。
5.C++规定=只能重载为成员函数。
赋值运算符可以连用.
6.constchar*c_str()const{returnstr);两种错误的情形:
char*p=s.c_str();strcpy(s。
c_str(),”tianggong1”);
7.a=b=”hello”;等价于a。
operator=(b。
operator=(”hello”));
8.(a=b)=c;等价于(a.operator=(b)).operator=(c);
9.深复制和浅复制:
两个对象的指针成员变量指向同一个地方,指向两个不同的地方.
10.将运算符重载为友元函数
11.重载插入运算符和流提取运算符:
cout是ostream类的对象。
ostream类和cout都是在iostream头文件中声明的.ostream类将"<<”多次重载为成员函数。
比如:
ostream&ostream:
:
operator<<(constchar*s){。
..return*this;)ostream&ostream:
:
operator〈〈(intn){。
。
。
return*this;)
12.返回值*this是cout的引用cout〈<”starwar”〈<5;等价于(cout.operator〈〈("starwar”)).operator〈〈(5);
13.重载强制类型转换运算符:
(类型名)对象等价于对象.operator类型名()
14.重载自增,自减运算符obj++CDemooperator++(int)
15.++objCDemooperator++(int)
继承与派生
1.继承与派生的关系:
A类派生出B类,B类继承了A。
派生类是通过对基类进行扩充和修改后得到的.基类所有成员自动成为派生类成员。
在派生类的成员函数中,不能访问基类的私有成员.派生类对象的体积等于基类对象的体积加上自己成员变量的体积。
在派生类对象中,包含着基类对象,且基类对象的存储位置位于新增的成员变量之前。
2.基类的构造函数和析构函数不能被派生类继承,需要自己重新定义。
如果基类构造函数没有定义,派生类也可不定义,用缺省.如果基类的构造函数定义,派生类构造函数一定要定义。
3.注意:
在基类和派生类中有同名成员,在派生类成员函数或派生类对象中访问同名成员,除非特别之指出,访问的是派生类的成员。
以下两种情况访问的是基类的成员:
s2。
CStudent:
:
PrintInfo();p->CStudent:
:
PrintInfo();
4.复合关系和继承关系:
复合关系,有,表现为封闭类,但不一定只是封闭类。
即一个类以另一个类的对象作为成员变量。
继承关系,是,类B继承类A,满足B所代表的事物也是A所代表的事物
5.类A知道类B:
类A的成员变量是类B的指针
6.////////导出类构造函数和析构函数的构建
基类的构造函数和析构函数不能被派生类继承。
如果基类没有定义构造函数,派生类也可以不定义构造函数,全都采用缺省的构造函数,此时,派生类新增成员的初始化工作可用其他公有函数来完成.
如果基类定义了带有形参表的构造函数,派生类就必须定义构造函数,提供一个将参数传递给基类构造函数的途径,以便保证在基类进行初始化时能获得必需的数据。
如果派生类的基类也是派生类,则每个派生类只需负责其直接基类的构造,不负责自己的间接基类的构造。
派生类是否要定义析构函数与所属的基类无关,如果派生类对象在撤销时需要做清理善后工作,就需要定义新的析构函数。
多态与虚函数
1.多态:
派生类对象的地址可以赋值给基类指针。
对于通过基类指针调用基类和派生类中都有的同名的,同参数的虚函数的语句,编译时不需要确定执行的是基类的还是派生类的虚函数。
当程序运行到该语句时,如果基类指针指向的是一个基类对象,则调用基类的虚函数;如果基类指向的是一个派生类对象,则调用派生类的虚函数。
这种机制成为多态;
2.面向对象程序设计语言有封装,继承,多态三种机制,这三种机制能够有效提高程序的可读性,可扩充性和可重用性。
3.多态指同一事物可以完成不同的功能。
分为编译时的多态和运行时的多态。
前者主要指函数的重载(包括运算符重载),对重载函数的调用。
后者主要与继承,虚函数等概念有关。
4.虚函数:
声明前面加了virtual关键字的成员函数。
virtual关键字只能在类定义中的成员函数声明处使用,不能在类外编写成员函数体时使用。
静态成员函数不能是虚函数.包含虚函数的类成为多态类。
5.多态可以简单地理解成同一条函数调用语句能调用不同的函数。
或者对不同的对象发同一消息,使得不同对象有各自不同的行为.
6.注意:
多态的语句调用的是哪个类的成员函数,是在运行时才能确定的,编译时不能确定。
因此多态的函数调用语句是动态联编的,普通的函数调用语句时静态联编的。
7.通过基类引用实现多态.通过基类的引用调用虚函数的语句是多态的,即通过基类的引用调用基类和派生类中的同名同参表的虚函数时引用的是哪个类的对象,调用该对象的虚函数。
8.多态的实现原理:
每一个有虚函数的类,都有一个虚函数表,列出了该类所有虚函数的地址。
该类的任何对象都存放着该虚函数表的指针。
位于对象存储空间的最前端,在数据成员之前,里面存放着虚函数表的地址。
9.多态的实现过程:
根据基类指针所指向的或基类引用所引用的对象中存放的虚函数表的地址,查找要调用的虚函数的地址,调用虚函数.
10.类的成员函数可以相互调用,在成员函数(静态,构造,析构除外)中调用同类的虚函数的语句是多态的。
11.在构造函数和析构函数中调用虚函数不是多态的,即编译时即可确定.如果本类有该函数,则调用本类的,本类没有调用直接基类的,基类没有,调用间接基类的。
。
。
12.注意:
只要在基类中某个函数被声明为虚函数,则在直接和间接派生类中,同名同参数的成员函数即使不写virtual也自动成为虚函数.
13.虚析构函数:
如果一个基类指针指向new出来派生类的对象,释放该对象时是通过该基类指针来完成的。
14.如果基类的析构函数是虚函数,派生类的析构函数即使不用virtual关键字也自动成为虚函数。
15.注意:
!
!
析构函数可以是虚函数,但构造函数不可以!
16.纯虚函数:
没有函数体的虚函数;在函数声明后加=0;
17.抽象类:
包含纯虚函数的类;不能生成独立的对象,但抽象类可以作为基类,派生出新类。
因此,独立的抽象类的对象不存在,但是被包含在派生类对象中的抽象类的对象,是可以存在的(但要实例化,有函数体)。
18.可以定义抽象类的指针或引用,让他们指向或引用抽象类的派生类的对象,实现多态.
19.如果一个类从抽象类派生而来,那么当且仅当它对基类中所有纯虚函数都进行覆盖并都写出函数体({}也是),它才能成为非抽象类。
函数调用也会带来降低效率的问题,因为调用函数实际上将程序执行顺序转移到函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。
这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执行。
因此,函数调用要有一定的时间和空间方面的开销,于是将影响其效率。
特别是对于一些函数体代码不是很大,但又频繁地被调用的函数来讲,解决其效率问题更为重要.引入内联函数实际上就是为了解决这一问题。
优点:
可以加快代码的执行速度,当程序中调用内联函数时,该函数直接嵌入到每个调用语句处,每次函数调用时都用相对应的一段代码代替。
可见它是以目标代码的增加为代价来换取时间的节省
主要解决功能相对简单、规模不大但使用相当频繁的程序运行效率问题。
使用内联函数时,遵守以下规则:
1。
内联函数体内不能包含任何静态变量,不能使用循环语句、switch;不能递归。
2。
内联函数的定义必须出现在第一次被调用之前。
3.如果函数返回类型为void,则不能有return语句。
二:
指针
通过指针引用数组元素
inta[10];
int*p;
p++是合法的,而a++是错误的。
a是数组名,它是数组的首地址,是常量;
指向函数的指针变量:
存放函数入口地址,指向的是程序代码存储区。
1、函数调用可以通过函数名调用,也可以通过指向函数的指针变量调用.
2、(*p)()表示定义一个指向函数的指针变量,在程序中把哪个函数的地址赋给它,它就指向哪一个函数。
3、给函数指针变量赋值时,只需给出函数名而不必给出参数。
p=max
4、用函数指针变量调用函数时,只需将(*p)代替函数名,在(*p)之后的括弧中根据需要写实参。
c=(*p)(a,b)
5、对指向函数的指针变量不能运算
constpointer
一个指针涉及到两个变量,一个是指针本身,另一个是指向的变量
1.指向常量的指针
const放在指针类型前,在程序中不能通过指针来间接修改指针所指向的内存空间的值,但可以改变指向的空间
inta=10;
constintb=20;
constint*pa=&a;
constint*pb=&b;
a=100;//ok
b=200;//error
*pa=100;//error
*pb=200;//error
pb=&a;//ok
pa=&b;//ok
2。
指针常量
const放在”*”和指针名之间,不能改地址能改所指向的值。
intb=28;
int*constpb=&b;
*pb=100;//ok
pb++;//error
在定义指针常量时,必须将其初始化。
3。
指向常量的指针常量
const在上述两个地方都加。
既不允许修改指针值,也不允许修改指针变量所指向的值
constinta=10;
constint*constpa=&a;
a=100;//error
*pa=100;//error
pa++;//error
三:
引用
标题
引用与指针的区别
引用是C++语言引进的概念,在C语言中没有。
1)、指针是变量,引用是别名
引用是别名,引用本身没有地址.
2)、指针可作数组元素、引用不可
例:
int*pa[5];//指针数组
inta[5];
int&rea[5]=a;//不可
…
3)、可以有空指针,不可有空引用
例:
int*p=null;//合法
int&re=null;//无意义
四:
类(class)
私有(private)的数据和函数,只允许本类的成员函数访问或调用;
保护(protected:
)的数据和函数,允许本类和本类派生类的成员函数访问或调用;
公有(public:
)的数据和函数,允许本类和其它类的函数访问或调用。
静态数据成员:
1.类的静态数据成员为该类的所有对象所共享。
2。
必须在类外文件作用域中的某个地方对静态数据成员赋初值(因为构造函数多次被调用,而静态数据成员只初始化1次):
<类型>〈类名>:
:
〈静态数据成员〉=<初值>
Const成员函数中确保不会修改任何本类对象的数据成员。
classconstfun
{
private:
inta;
public:
voidnonconstFunc()
{
a=18;//ok
}
voidFunc()const
{
a=18//error
}
}
this指针:
this指针是指向对象的指针,隐含在类的成员函数中,用来指向成员函数所属类的正在被操作对象。
this指针可以看作是类自身的一个引用。
构造函数的调用顺序
对于构造函数,先执行基类的,再执行对象成员的,最后执行派生类的.
对于析构函数,先执行派生类的,再执行对象成员的,最后执行基类的.
导出类构造函数和析构函数的构建
基类的构造函数和析构函数不能被派生类继承。
如果基类没有定义构造函数,派生类也可以不定义构造函数,全都采用缺省的构造函数,此时,派生类新增成员的初始化工作可用其他公有函数来完成。
如果基类定义了带有形参表的构造函数,派生类就必须定义构造函数,提供一个将参数传递给基类构造函数的途径,以便保证在基类进行初始化时能获得必需的数据。
如果派生类的基类也是派生类,则每个派生类只需负责其直接基类的构造,不负责自己的间接基类的构造。
派生类是否要定义析构函数与所属的基类无关,如果派生类对象在撤销时需要做清理善后工作,就需要定义新的析构函数。
五:
多重继承
解决二义性问题
解决方法一:
用类名来限定(主要解决方法)为避免二义性,可在调用时加上基类的名称,如A:
:
print()或B:
:
print()。
解决方法二:
同名覆盖在C中声明一个同名成员函数print(),f()再根据需要调用A:
:
print()或B:
:
print()
解决方法三:
使用虚函数
面向对象设计的三大机制:
数据封装、继承、多态.
继承:
研究的是类与类之间的层次关系。
多态性:
指不同的对象接收到相同的消息时产生不同的响应动作,即对相同的函数名,却执行不同的函数体.
函数重载和运算符重载实现类的一种多态性。
静态联编和动态联编
联编(binding):
是将函数调用与相应的函数体代码彼此关联的过程。
静态联编(staticbinding):
如果联编过程在程序开始运行前的编译阶段完成。
例如:
重载函数:
voidfun(inta,intb)
voidfun(floatx,floaty)
voidfun(charc)
函数名字相同,但各自参数不同,编译器能根据函数参数的类型和个数自动选择相应的函数体编译.
动态联编(dynamicbinding)
在程序运行时进行的联编方式。
例如:
虚函数
C++中的虚函数,由于其函数名、返回值、函数参数完全相同,但函数体不同,因此编译阶段无法确定函数调用与哪个函数体关联,只能由系统在程序运行时确定。
六:
虚函数
虚函数(virtualfunction)—-——运行时多态
在定义某一基类(或其派生类)时,若将其中的某一函数成员的属性说明为virtual,则称该函数为虚函数。
若基类中某函数被说明为虚函数,则意味着其派生类中也要用到与该函数同名、同参数表、同返回类型、但函数体不同.
虚函数存在继承环境中。
虚函数成员的定义语法:
virtual函数类型 函数名(形参表)
{
函数体
}
程序举例
classBaseClass
{
public:
virtualvoidshow(){cout<<”Baseclass"〈〈endl;}
//如果不加关键字virtual,运行的结果都是"Baseclass”;
};
classDerived1:
publicBaseClass
{
public:
voidshow(){cout<<"Derivedclass1”<〈endl;}
};
classDerived2:
publicBaseClass
{
public:
voidshow(){cout<〈"Derivedclass2”<〈endl;}
};
intmain(){
BaseClassobj;
BaseClass*p;
Derived1obj1;
Derived2obj2;
p=&obj;
p—>show();
p=&obj1;
p->show();
p=&obj2;
p->show();
return0;
}
通过虚函数,达到了用基类指针访问派生类对象成员函数的目的,这样,只要声明了基类指针,就可以使不同的派生类对象产生不同的函数调用,实现了程序的运行时多态。
运行多态应该使用虚函数,并通过指针、引用或者成员函数调用虚函数
纯虚函数和抽象类
纯虚函数(purevirtualfunction):
在基类中声明虚拟函数而不给出具体的定义,把它的定义放在各个导出类中,此种函数为纯虚函数
通过基类指针或引用可以调用所有派生类的虚函数。
抽象类:
(abstractclass)
声明了虚函数的类,基类只用于继承,仅作为一个接口,具体的功能则在派生类中实现。
注意:
从抽象类可以派生出具体的或抽象类,但不能从具体类派生出抽象类.
虚基类
虚基类的引入
用于有共同基类的场合
声明
以virtual修饰说明基类例:
classB1:
virtualpublicB
作用
主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题.
为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝
类模板
C++中实现多态的另一种方法是类模板
类模板可以使用户为类定义一种模式,使得类中的一些数据成员和成员函数的参数,以及成员函数的返回值能够娶任意类型。
#include
template
public:
Tbuffer[10];
//T类型的数据成员buffer数组大小固定为10(灵活性差!
)
TgetData(intj);//获取T类型buffer(数组)的第j个分量
};
template〈classT>
TTestClass〈T>:
:
getData(intj){
return*(buffer+j);
};
voidmain(){
TestClass〈char>ClassInstA;
//char取代T,从而实例化为一个具体的类
charcArr[6]="abcde”;
for(inti=0;i〈5;i++)
ClassInstA。
buffer[i]=cArr[i];
for(i=0;i<5;i++){
charres=ClassInstA.getData(i);
cout〈〈res〈<"";
}
cout〈〈endl;
程序执行后的显示结果如下:
abcde
2。
113。
224.335。
446.557.6
既使用类型参数又使用普通参数的类模板示例
#include〈iostream.h〉
#include"string。
h"
template public: Tbuffer[i]; //T类型的buffer,其大小随普通形参i的值变化(灵活性大! ) TgetData(i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 知识点 总结 范本 模板