第七章
函数在调用前要先声明。
new和delete可以用来分配内存和释放。虽然malloc和free也保留了,但不推荐使用。
delete运算符使用的一般格式为delete [] 指针变量
有时需要使几种不同类型的变量存放到同一段内存单元中,应使用union。声明的一般形式为:
union 类型名{ 成员表列};
枚举类型:enum weekday{sun,mon,tue,....}
声明了枚举类型之后,可以用它来定义变量。如 weekday workday, week_end;
typedef int INTEGER;
typedef float REAL;
第八章
如果在类的定义中既不指定private,也不指定public,则系统就默认为是私有的。 ,
归纳以上对类类型的声明,可得到其一般形式如下:
class
类名
{
private:
私有的数据和成员函数
public:
公用的数据和成员函数
};
为了减少时间开销,如果在类体中定义的成员函数中不包括循环等控制结构,C++会自动把它们作为内置函数处理。
只有在类外定义的成员函数规模很小而调用频率较高时,才将此成员函数指定为内置函数。
此每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。
在头文件中包含了类的声明,因此在程序中就可以用该类来定义对象。由于在类体中包含了对成员函数的声明,在
程序中就可以调用这些对象的公用成员函数。为了实现上一节所叙述的信息隐蔽,对类成员函数的定义一般不放在
头文件中,而另外放在一个文件中。
请注意:student.h放在用户当前目录中,因此在文件名两侧用双撇号包起来″student.h″而不用尖括号
<student.h>
否则编译时会找不到此文件
库包括两个组成部分: 类声明头文件;已经过编译的成员函数的定义,它是目标文件
户只需把类库装入到自己的计算机系统中(一般装到C++ 编译系统所在的子目录下),并在程序中用include命令行
将有关的类声明的头文件包含到程序中,就可以使用这些类和其中的成员函数,顺利地运行程序。
第九章
构造函数:略
也可采用以下形式:
Box::Box(int h, int w, int len):height(h),width(w),length(len){}
Box(int h=10,int w=10,int len=10); //在声明构造函数时指定默认参数
析构函数:~
析构函数的作用并不是删除对象,而是在撤销对象
占用的内存之前完成一些清理工作,使这部分内存
可以被程序分配给新对象使用。
际上,析构函数的作用并不仅限于释放资源方面,它还可以被用来执行用户希望在最后一次使用对象之后所执行的
任何操作
果在函数中定义静态局部对象,则只在程序第一次调用此函数建立对象时调用构造函数一次,在调用结束时对象并
不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。
果构造函数只有一个参数,在定义数组时可以直接在等号后面的花括号内提供实参。
tudent Stud[3]={ //定义对象数组
Student(1001,18,87), //调用第1个元素的构造函数,为它提供3个实参
Student(1002,19,76), //调用第2个元素的构造函数,为它提供3个实参
Student(1003,18,72) //调用第3个元素的构造函数,为它提供3个实参
}
定义指向成员函数的指针变量应该采用下面的形式:
void (Time:: *p2)();
可以让它指向一个公用成员函数,只需把公用成员函数的入口地址赋给一个指向公用成员函数的指针变量即可。
p2=&Time∷get_time;
定义常对象的一般形式为
const 类名 对象名(实参表列);
也可以把const写在最左面
mutable int count;
如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们,例如只用于输出数据等
void get_time( ) const; //注意const的位置在函数名和括号之后
如果已定义了一个常对象,只能调用其中的const成员函数,而不能调用非const成员函数
指向对象的常指针(指针值始终为初值,不能改变指向)的一般形式为
类名 *const 指针变量名;
指向常对象的指针变量:
const 类名 *变量名
const Time &t1=t;对象的常引用,不能改变所指位置的值
在执行运算符时,在释放内存空间之前,自动调用析构函数,完成有关善后清理工作。
象之间的赋值也是通过赋值运算符“=”进行的
对象的赋值只对其中的数据成员赋值,而不对成员函数赋值
类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现严重后果
对象的复制:Box box2(box1);
如果用户自己未定义复制构造函数,则编译系统会自动提供一个默认的复制构造函数,其作用只是简单地复制类中
每个数据成员。
C++还提供另一种方便用户的复制形式,用赋值号代替括号,如Box box2=box1;
复制构造函数的形式是这样的:
Box::Box(const Box &b){
height=b.height;
width=b.width;
...}
静态数据成员可以被初始化,但只能在类体外进行初始化。
静态数据成员既可以通过对象名引用,也可以通过类名来引用。
静态成员函数可以通过类调用,也可以通过对象名调用,例如
Box::volume();
a.volume();
静态成员函数没有this指针,不能访问本类中的非静态成员。
静态成员函数可以直接引用本类中的静态数据成员,如果一定要引用本类的非静态成员,应该加对象名和成员运算
符"."
类体中用friend对其进行声明,此函数就称为本类的友元函数。友元函数可以访问这个类中的私有成员。
A在B类的定义体中用以下语句声明类为其友元类:
friend B;
友元类关系不传递,在工作中一般不使用。
有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,此时可以声明一个通用的类模板:
template<class 类型参数名>
实际使用时,在尖括号内指定实际的类型名:Compare<int>,此时Compare中的numtype都被替换成int
在类外定义类成员函数时,需要使用如下形式:
numtype Compare<numtype>::max(){......}
第十章 运算符重载
第十一章 继承与派生
派生类的声明方式:class Student1: public Student{...}
公用继承:基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。
私有继承:基类的公用成员和保护成员在派生类中成了私有成员。其私有成员仍为基类私有。
protected继承:基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。
派生类构造函数的一般形式为:
派生类构造函数名(总参数表列):基类构造函数名(参数表列)
Student1(int n, string nam, char s, int a, string ad):Student(n, nam, s){
age=a;
addr=ad;
}
也可包含内嵌对象:
派生类构造函数名(总参数表列):基类构造函数名(参数表列),子对象名(参数表列),例如:
student(int n, string nam, int n1, string nam1, int ad, string ad):Student(n, nam), monitor(n1, nam1)
派生时,派生类是不能继承基类的析构函数的,也需要通过派生类的析构函数去调用基类的析构函数。在派生类中
可以根据需要定义自己的析构函数,用来对派生类中所增加的成员进行清理工作。
多重继承:class D: public A, private B, protected C
派生类构造函数名(总参数表列):基类1构造函数(参数表列),基类2构造函数(参数表列){...}
多重继承引起的二义性问题:两个基类有同名成员、两个基类和派生类三者都有同名成员。
规则:基类的同名成员在派生类中被屏蔽。
虚基类:在继承间接共同基类时只保留一份成员(需要在所有直接派生类中声明虚基类)。
class B: virtual public A{...}
class C: virtual public A{...}
在最后的派生类中不仅要对直接基类进行初始化,也要对虚基类初始化。
派生类对象可以替代基类对基类对象的引用进行赋值或初始化。
第十二章
静态多态性在编译时决定调用哪个函数,动态多态性在运行时。静态多态性通过函数重载和运算符重载实现,动态
多态性通过虚函数实现。
虚函数:用同一个调用形式,既能调用派生类又能调用基类的同名函数。在程序中不是通过不同的对象名去调用不
同派生层次中的同名函数,而是通过指针调用它们。
虚函数声明:virtual void play();
当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。
在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同。
通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同类的同名函数,只要先用基类
指针指向即可。
确定调用的具体对象的过程称为关联(binding)。
一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(
包括个数和类型)和函数返回值类型的同名函数。
当基类的析构函数为虚函数时,无论指针指的是同一类族中的哪一个类对象,系统会采用动态关联,调用相应的析构函数,对该对象进行清理工作。
virtual float area( ) const =0;//纯虚函数
纯虚函数没有函数体,只是通知编译系统:在这里声明一个虚函数,留待派生类中定义。
凡是包含纯虚函数的类都是抽象类。