函数重载的条件: 1).函数名相同
2).函数的参数不同(参数个数、参数类型或参数顺序中必须有一个不同)
3).同名函数的功能应相同或相近,不要用同一个函数名去实现完全不相干的功能 注:函数的返回类型不同不能作为重载的条件
内联函数的好处:
1).调用函数时需要一定的时间和空间的开销
2).内联函数可以提高效率,在编译时将所调用的内置函数的代码直接嵌入到主调函数中,而不是将流程转出去。
引用的定义:
如果函数的形参是一个引用,那么参数的传递方式就是引用传递,形参就是实参对应的引用; 换句话说,形参和对象的实参就是一回事,对形参值的改变,就会影响到实参(即:实参值也会做相应的改变)。
字符串的三种形式:
(1)用双引号括起来的字符串常量; (2)存放于字符数组中的字符串;
(3)string对象。string是C++标准模板库中的一个类,专门用于处理字符串 字符数组可以用cout输出;
要使用字符串库函数需要包含cstring头文件;
String的使用方法:
string类型并不是C++语言的基本数据类型,而是C++标准模板库中的一个“类”; 在使用方法上,字符串类型同char,int类型一样,可以用来定义变量
new动态开辟空间的使用方法:与C语言的malloc
1
注:用new 分配数组空间时不能指定初值
如果由于内存不足等原因而无法正常分配空间,则new 会返回一个空指针NULL,程序可以根据该指针的值判断分配空间是否成功
用new运算符动态分配的空间,在使用完后,都需要使用delete运算符进行释放! Delete p; Delete p[];
要访问用new所开辟的空间,无法直接通过变量名进行,只能通过指针进行访问。
如果是想要在程序之中弄出一个动态结构体的话,那么就可以用a=new abs;来动态开辟一个结构体空间,但是同样的要在最后加上delete a;如果是a=new abs[10];OK一样的在最后面加上delete a[];
String的所有知识点的整合:
a) string s; //生成一个空字符串s
b) string s(str) //拷贝构造函数 生成str的复制品
c) string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值
d) string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
e) string s(cstr) //将C字符串作为s的初值
f) string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。 g) string s(num,c) //生成一个字符串,包含num个c字符
h) string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值 i) s.~string() //销毁所有字符,释放内存 http://www.jb51.net/article/41725.htm详细资料
封装性:
一是将有关的数据和操作代码封装在一个对象中,形成一个基本单位,各个对象之间相对独立,互不干扰。
二是将对象中某些部分对外隐蔽,即隐蔽其内部细节,只留下少量接口(就是public成员函数),以便与外界联系,接收外界的消息,这种对外界隐蔽的做法称为信息隐蔽(imformation hiding)。信息隐蔽还有利于数据安全,防止无关的人了解和修改数据。
抽象:
抽象的作用是表示同一类事物的本质。
在C++中,同一类事物抽象出来的类型就称为“类(class)”。类是对象的抽象,而对象则是类的特例,或者说是类的具体表现形式。
继承与重用:
C++提供了继承机制,采用继承的方法可以很方便地利用一个已有的类建立一个新的类。这就是常说的“软件重用”(software reusability) 的思想
多态性:
2
如果有几个相似而不完全相同的对象,有时人们要求在向它们发出同一个消息时,它们的反应各不相同,分别执行不同的操作。这种情况就是多态现象。
在C++中,所谓多态性(polymorphism)是指:由继承而产生的相关的不同的类,其对象对同一消息会作出不同的响应。多态性是面向对象程序设计的一个重要特征,能增加程序的灵活性。
作用域限定符的定义:
“::”是作用域限定符(field qualifier)或称作用域运算符,用它声明函数是属于哪个类的。 如果在作用域运算符“::”的前面没有类名,或者函数名前面既无类名又无作用域运算符“::”,则表示函数不属于任何类,不是成员函数,而是全局函数,即非成员函数的一般普通函数。
成员访问符:
通过对象名和成员运算符访问对象中的成员,就是:A.b,那一个小点就是成员运算符。 在子类继承了父类的函数之后,如果进行了对函数的重载,那么如果想使用父类的函数就应该用父类的名字加上作用域限定符。因为所有的函数在汇编过程中都是会变成A::b,B::b这样的格式进行存放,所以说在调用成员函数的时候也可以只用作用域限定符。
子类可以通过b.A::c();的格式对父类继承下来的被重载了的函数进行输出,当然没有重载也可以。
对象、方法、消息:
类的成员函数在面向对象程序理论中被称为“方法”(method),“方法”是指对数据的操作。
外界是通过发“消息”来激活有关方法的。所谓“消息”,其实就是一个命令,由程序语句来实现。例如:stud.display( ); 就是向对象stud 发出一个“消息”,通知它执行其中的display“方法”(即display函数)
类的存储空间的存放规则:
每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间,因为共用一个函数空间,只是一个对象在调用这个函数的时候会用this指针,指向调用这个成员函数的对象。 类在定义的时候不分配空间的,因为某个类的说明只是抽象的东西,只有变成了具体的对象的时候,计算机才会为其分配空间,进行对其的操作。所以在定义累的时候,不能给之中的数据成员赋初始值,只能用构造函数进行初始化。
构造函数:
1).C++提供了构造函数(constructor)来处理对象的初始化;
2).构造函数是一种特殊的成员函数,不需要用户来调用它,而是在建立对象时自动执行; 3).构造函数的名字必须与类名同名,不能由用户任意命名; 4). 它不具有任何类型,不返回任何值;
5).用户根据初始化的要求设计函数体和函数参数;
6).如果用户自己没有定义构造函数,则C++系统会自动生成一个构造函数,只是这个构造函数的函数体是空的,也没有参数,不执行初始化操作
构造函数的用法:
3
构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即定义对象时不指定实参值,编译系统就使形参取默认值。
析构函数:
1).析构函数(destructor)也是一个特殊的成员函数,它的作用与构造函数相反,析构函数的名字是类名的前面加一个“~”符号;
2).析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以被程序分配给新对象使用;
3).当对象的生命期结束时,会自动执行析构函数;
析构函数的要点:
1).如果在一个函数中定义了一个对象(它是自动局部对象),当这个函数调用结束时,对象应该释放,在对象释放前自动执行析构函数
2). static局部对象在函数调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用static局部对象的析构函数
3). 如果定义了一个全局对象,则在程序的流程离开其作用域时(如main函数结束或调用exit函数)时,调用该全局对象的析构函数
4). 如果用new运算符动态地建立了一个对象,当用delete运算符释放该对象时,先调用该对象的析构函数(如果动态分配空间的对象,如果没有用delete的话,那么程序与文件之间的联系就不会断绝)
常成员函数和常数据成员的需要关注的要点:
1).如果一个对象被声明为常对象,则不能调用该对象的普通的成员函数(除了由系统自动调用的隐式的构造函数和析构函数)
2).如果需要使用常对象来调用成员函数,那么要求将该成员函数定义为常成员函数: Void get_time() const; 注意:常成员函数可以访问常对象中的数据成员,但仍然不允许修改常对象中数据成员的值。
3).如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们 4).const是函数类型的一部分,在声明函数和定义函数时都要有const关键字,在调用时不必加const
5).常成员函数可以引用const数据成员,也可以引用非const的数据成员。
6).const数据成员可以被const成员函数引用,也可以被非const的成员函数引用
常指针和常变量指针:
1).将指针变量声明为const型,这样指针值始终保持为其初值,不能改变
类名 * const 指针变量名(如果const放在*的前面,那么就是常量,指向的数值不能改变)。
2). 指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为const的变量。此时不能通过此指针变量改变该变量的值。如果希望在任何情况下都不能改变变量的值,则应把它定义为const型。
3). 如果函数的形参是指向非const型变量的指针,实参只能用指向非const变量的指针,而不能用指向const变量的指针,这样,在执行函数的过程中可以改变形参指针变量所指向的变量(也就是实参指针所指向的变量)的值。
4
对象的常应用:
在C++面向对象程序设计中,经常用常指针和常引用作函数参数。这样既能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝。用常指针和常引用作函数参数,可以提高程序运行效率。 Void fun(const time &t);
Const型数据的小结: 数据成员 非const的数据成员 const数据成员 const对象的数据成员 形式 Time const t1; Void time::fun()const; Time *const p; const Time *p; Time &t1=t; 含义 T1是常对象,其值在任何情况下都不会改变 Fun是time类中的常成员函数,可以引用,但不能修改本类中的数据成员 p是指向Time对象的常指针,p的值(即p的指向)不能改变 p是指向Time类常对象的指针,其指向的类对象的值不能通过指针来改变 t1是Time类对象t的引用,二者指向同一段内存空间 非const成员函数 可以引用,也可以改变值 值 可以引用,但不可以改变值 不允许调用此成员函数 可以引用,但不可以改变值 可以引用,但不可以改变值 const成员函数 可以引用,但不可以改变 对象的赋值:
两个同类对象之间的赋值通过赋值运算符“=”进行,对象赋值实际上的过程是通过成员复制来完成的,即将一个对象的成员值一一复制给另一个对象的对应成员
对象的复制:
1). 用一个已有的对象快速地复制出多个完全相同的对象;
2). 对象复制与定义对象方式类似,但是括号中给出的参数不是一般的变量,而是对象。 3). 在复制对象时调用一个特殊的构造函数——复制构造函数(copy constructor);
4). 如果用户自己未定义复制构造函数,则编译系统自动提供一个默认的复制构造函数,其作用只是简单地复制类中每个数据成员,其形式是这样的: // The copy constructor definition.
Box::Box(const Box& b) {
height = b.height; width = b.width; length = b.length; }
5). C++还提供另一种方便用户的复制形式,用赋值运算符代替括号
复制构造函数使用的时期:
5
1). 程序中需要新建立一个对象,并用另一个同类的对象对它初始化
2). 当函数的参数为类的对象时。在调用函数时需要将实参对象完整地传递给形参,也就是需要建立一个实参的拷贝,这就是按实参复制一个形参,系统是通过调用复制构造函数来实现的,这样能保证形参具有和实参完全相同的值。
3). 函数的返回值是类的对象。在函数调用完毕将返回值带回函数调用处时。此时需要将函数中的对象复制一个临时对象并传给该函数的调用处 静态数据成员使用的时间:
1). 如果想在同类的多个对象之间实现数据共享,也不采用全局对象,可以用静态的数据成员。
2).静态数据成员是一种特殊的数据成员,以static开头
3).静态数据成员不属于某一个对象,是在所有对象之外单独开辟空间
4).静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放空间 5).静态数据成员可以初始化,但只能在类体外进行初始化
6).静态数据成员既可以通过对象名引用,也可以通过类名来引用
int Box::height=10;可以用两种方式对其进行调用:b.height;或者Box::height;
静态成员函数:
1).成员函数也可以定义为静态的,在类中声明函数的前面加static就成了静态成员函数 2).静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员
3).静态成员函数并不属于某一对象,它与任何对象都无关,因此静态成员函数没有this指针
4).静态成员函数不能访问本类中的非静态成员
友元函数:
1). 友元(friend)可以访问与其有好友关系的类中的私有成员。友元包括友元函数和友元类。
2).如果在本类以外的其他地方定义了一个函数,在类体中用friend对其进行声明,此函数就称为本类的友元函数
3).友元函数可以访问这个类中的私有成员
友元类:
1).若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员 2)声明友元类的一般形式为 class A {
friend B; …… };
运算符重载的定义:
1). 函数重载就是对一个已有的函数赋予新的含义,使之实现新的功能,也就是一名多用。 2).运算符也可以重载,它的原理与函数重载是一致的,用户可以根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。
6
重载运算符的方法:
1). 定义一个重载运算符的函数 2).运算符重载实质上是函数的重载
3).在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算 友元法:friend Complex operator + (Complex &c1, Complex &c2); 成员函数法:Complex operator + (Complex &c2);
运算符重载的一些规定和习惯:
1).将双目运算符重载函数作为成员函数,它可以通过this指针自由地访问本类的数据成员,因此可以少写一个函数的参数;
2).将双目运算符重载为友元函数时,在函数的形参列表中必须有两个参数,不能省略,形参的顺序任意,不要求第一个参数必须为类对象。
3).一般将双目运算符重载为友元函数形式,将单目运算符重载为类成员函数形式。
前置++的重载函数说明是Complex operator++(); 后置++的重载函数说明是Complex operator++(int);
流运算符重载:
1). 如果想用”<<”和”>>”来输出和输入用户自定义类型的数据,则必须对它们重载。 对”<<“和”>>”重载的函数形式:
Ostream& operator <<(ostream &,Complex &); Istream& operator >>(istream &,complex &);
2).只能将重载”>>”和”<<“的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。
运算符重载注意事项:
1). C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载; 2).C++中绝大部分的运算符允许重载,不允许重载的运算符有以下五个: . (成员访问符); *(成员指针访问符); ::(作用域限定符); Sizeof(长度运算符); ?:(条件运算符);
3). 重载不能改变运算符运算对象(即操作数)的个数 4).重载不能改变运算符的优先级别。 5).重载不能改变运算符的结合性。
6).重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与前面第(3)点矛盾。
7). 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。也就是说,参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。
8). 用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载。
① 赋值运算符(=)可以用于每一个类对象,可以利用它在同类对象之间相互赋值。
7
② 地址运算符&也不必重载,它能返回类对象在内存中的起始地址。
9). 应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能。
数据的类型转换有以下几种方法: 1).隐类型转换。 2).显类型转换。 3).自定义类型转换:
1转换构造函数: ○
1).将一个其他类型的数据转换成一个类的对象 2).转换构造函数只有一个形参,其形式类似于: Complex(double r) {
Real=r;image=0; }
其实构造函数就是各种high,随便用,一般都是不会出错的。 2类型转换函数: ○
1). 类型转换函数的作用是将一个类的对象转换成另一类型的数据 2).一般格式为:
Operator 需要转换成数据类型() //其实就是对系统自带的强制类型转换重载
{
Return „„;
}
继承与派生:
1). 一个新类从已有的类那里获得其已有的特性,这种现象称为类的继承,通过继承,一个新建子类从已有的父类那里获得父类的特性;
2).从另一角度说,从已有的类(父类)产生一个新的子类,称为类的派生。
3).关于基类和派生类的关系,可以表述为: 派生类是基类的具体化,而基类则是派生类的抽象
继承的方式有三种: 1).public
2).private(当如果是没有写的话,那么就是私有继承) 3)protected
派生类的成员中的数据成员成员函数除了从基类继承之外,还有自己定义的数据成员的成员函数,如果想要对父类继承下来的私有数据进行调用的话,即使是公共继承,也必须调用从基类中继承下来的成员函数进行调用。
不同的继承方式决定了基类成员在派生类中的访问属性:
1).公用继承(public inheritance):基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。
2).私有继承(private inheritance):基类的公用成员和保护成员在派生类中成了私有成员。
8
其私有成员仍为基类私有。
3).受保护的继承(protected inheritance):基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。
在基类中定义的protected类型的数据成员,在子类中是可以用子类的成员函数进行调用的,而private只能在基类的成员函数中进行调用。
对基类的构造函数调用需要注意的地方:
1).在设计派生类的构造函数时,不仅要考虑派生类所增加的数据成员的初始化,还应当考虑从基类继承来的数据成员初始化;
2).解决这个问题的思路是: 在执行派生类的构造函数时,调用基类的构造函数。(积累的构造函数一定要被使用,不能不使用,比如你在基类中对默认构造函数进行了重载,那么,你必须要对从基类中继承下来的数据成员进行初始化)
对有子对象的子类进行初始化操作时:
1).含有子对象的派生类定义构造函数的一般形式为: 派生类构造函数名(总参数表列)
: 基类构造函数名(参数表列), 子对象名(参数表列) { 派生类中新增数成员据成员初始化语句 } 2).执行的循序为:
① 调用基类构造函数,对从基类继承而来的数据成员初始化; ② 调用子对象构造函数,对子对象数据成员初始化;
③ 再执行派生类构造函数本身,对派生类数据成员初始化。
多重派生的话,子类只要对上一级负责就够了,在初始化的时候,初始化列表只要加上上一级父类的初始化默认函数。
析构函数:
1).在派生时,派生类不能继承基类的析构函数;
2).在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理;
3).调用的顺序与构造函数正好相反: 先执行派生类自己的析构函数,对派生类新增加的成员进行清理,然后调用子对象的析构函数,对子对象进行清理,最后调用基类的析构函数,对基类进行清理
多重继承:
1).参数列表为:
派生类构造函数名(总参数表列)
: 基类1构造函数(参数表列), 基类2构造函数(参数表列), 基类3构造函数 (参数表列)
{ 派生类中新增数成员据成员初始化语句 }
2).执行顺序为:
派生类构造函数的执行顺序同样为: 先调用基类的构造函数,再执行派生类构造函
9
数的函数体。调用基类构造函数的顺序是按照声明派生类时基类出现的顺序。
虚继承:
1).如果在虚基类中定义了带参数的构造函数,而且没有定义默认构造函数,则在其所有派生类(包括直接派生或间接派生的派生类)中,通过构造函数的初始化表对虚基类进行初始化;
2).在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。 格式如下:class N //定义基类N { N(int i) { a=i; } //基类构造函数,有一个参数 „};
class A : virtual public N //N作为A的虚基类 { A(int n) : N(n){ } //在初始化表中对虚基类初始化 „};
class B: public N //B作为N的虚基类 { B(int n) : N(n){ } //在初始化表中对虚基类初始化 „};
class C : public A, public B //在初始化表中对所有基类初始化 { C(int n): N(1), A(2), B(3){ } „};
只有指针和引用才能用子类对基类赋值操作。因为没有足够的空间和成员让基类的内容传递到衍生类之中。
多态性的定义:
1). 向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。
2).静态多态性:在程序编译时系统就能决定调用的是哪个函数,又称编译时的多态性,函数重载和运算符重载实现的多态性属于静态多态性;
3).动态多态性:在程序运行过程中才动态地确定操作所针对的对象,又称运行时的多态性,动态多态性通过虚函数(virtual function)实现。
关联的定义:
关联:把一个标识符和一个存储地址联系起来。
1).静态关联:在编译时即可确定其调用的函数属于哪一个类,由于是在运行前进行关联的,故又称为早期关联(early binding)。函数重载属静态关联
2).动态关联:在运行阶段把虚函数和类对象“绑定”在一起。动态关联是在编译以后的运行阶段进行的,因此也称为滞后关联(late binding)。
虚函数的作用:
1).虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类).
10
指针或引用来访问基类和派生类中的同名函数。
2).简单的说就是:用同一个调用形式,既能调用派生类又能调用基类的同名函数 。这里的“同一种调用形式”是用指针或引用的形式来调用同名函数,而非使用对 象的形式。
使用虚函数的方法:
1).在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用。在类外定义虚函数时不必再加virtual。
2).在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。
3).定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。 通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。
虚函数调用的结果是和本身的成员类型无关,虚函数的定义的动态的,所以说只有在调用的时候系统才是知道要调用的函数是什么。所以说你当时被什么东西附了值,那么就输出来的结果就是和你被赋值的类型相关。
虚函数的意义:
如果使用new运算符对派生类动态分配空间,且将该派生类对象的地址赋予一个基类指针,那么在使用delete运算符释放空间时,只会调用基类的析构函数,而不会调用派生类的析构函数。
解决该问题的方法:使用虚析构函数。
抽象类的定义:
凡是包含纯虚函数的类都是抽象类;
抽象类的作用是作为一个类族的共同基类,或者说,为一个类族提供一个公共接口; 如果在抽象类所派生出的新类中对基类的所有纯虚函数进行了定义,那么这些函数就被赋予了功能,可以被调用。这个派生类就不是抽象类,而是可以用来定义对象的具体类(concrete class)。如果在派生类中没有对所有纯虚函数进行定义,则此派生类仍然是抽象类,不能用来定义对象。
11
因篇幅问题不能全部显示,请点此查看更多更全内容