昨天的复习让自己有不小的收获,对一些基础知识也有了更加深刻的理解,所以今天在昨天的复习基础上继续往
后复习,巩固:
(1)继承时的名字遮拦:
派生类的成员和基类中的成员重名,那么就会遮拦从基类继承过来的成员,派生类在使用该成员时,实际上是派
生类新增的成员,不是从基类中继承来的;
在基类和派生类中,不管是成员变量,还是成员函数,只要名字一样就会造成遮蔽;
(2)派生类的构造函数:
构造函数不能被继承,派生类的构造函数可以调用基类的构造函数类实现;
如:Student::Student(char *name, int age,float score):People(name,age), m_score(score){},在这里People类是
Student类的基类;
(3)构造函数和析构函数的调用顺序:
派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的构造函数;基类的析构函数不能被继承;
举个例子吧: 基类A,派生出B,B再派生出C;
则它们的构造函数调用顺序为:A,B,C
析构函数调用顺序为:C, B, A
(4)多继承类:
class C:public A, public B, public D
{
};
多继承下的构造函数,和单继承一样,都是调用基类的构造函数;
(5)命名冲突:
当多继承的时候,如果c分别从A和B继承函数,如果是函数名有相同,编译器会报错,这个时候要加上::来进
行说明;
(6)引用:
相当于一个别名,语法格式:type &name = data;
int xiaoW;
int &xiaoG = xiaoW;
a. &不是地址预算法,是一个引用运算符;
b. xiaoG,xiaoW变量的地址和值都是一样;
c. 引用只能初始化,不能先声明后赋值,相当于一个常量;
d. 在声明一个引用的时候必须初始化;
e. 这个别名别人不能用,只能这个变量使用;改变变量的值,这个别名的值也会改变;
开始定义初始化的时候&表示引用运算符;
引用初始化后,&表示区地址运算符;
可以对对象和变量进行引用,但是不能对类进行引用,因为类没有内存地址;
(7)引用和指针的比较:
a. 指针可以是空的,引用不能为空;
b. 指针可以改变,引用初始化了,引用就不能改变成别的引用;
c. 在堆上创建了一块内存,必须使用指针指向;不能使用引用;
(8)虚函数:
有了虚函数才能构成多态;
a. 在虚函数的声明前加virtual关键字,在定义处可加可不加;
b. 只在基类的相关函数前加virtual,在派生类中有遮蔽关系函数名参数都一样的都会自动转为虚函数;
c. 基类中声明虚函数,在派生类没有定义遮蔽关系的函数,自动调用其基类的虚函数;
d. 派生类的虚函数遮蔽基类虚函数,才能构成多态;
e. 构造函数不能是虚函数;
f. 析构函数可以声明为虚函数,有的时候必须声明为虚函数
(9)虚析构的必要性:
创造的基类指针pa指向派生类地址的时候,在释放地址delete pa的时候,只释放基类的析构函数,不释放派生类
的析构函数;因为pa是基类的指针,只能释放基类析构;
如果要是一起释放基类和派生类,要把基类的析构函数设置成虚析构,这样可以继承。
(10)静态绑定和动态的绑定:
a. 静态绑定:指在编译过程中就能确定所调用的是哪一个函数。又称为编译时多态性;
主要是函数重载,运算符重载;
b. 动态的多态性: 在程序运行的时候才能确定是哪一个函数。又称为运行时多态。
主要是继承和虚函数。
非虚函数都是静态绑定,虚函数都是动态绑定;
(11)纯虚函数和抽象类:
语法格式:
virtual 返回值类型 函数名(参数) = 0;
a. 纯虚函数没有函数体,之有 声明;=0 只表示是纯虚函数,
b. =0 不表示返回值是0,只是一个形式,告诉编译器这是纯虚函数
c. 包含纯虚函数的类称为抽象类;
d. 抽象类通常称为基类,让派生类去实现纯虚函数,派生类必须实现纯虚函数才能被实例化;
纯虚函数注意:
a. 一个纯虚函数可以使类成为抽象基类,但是抽象基类里面除了包含纯虚函数外,还可以包含其他的成员函数
和变量;
b. 只有类中的虚函数才能声明为纯虚函数,普通的成员函数和顶层函数不能声明为纯虚函数。
(12)typeid的运算符:获取表达式的类型信息
格式:
typeid( dataType )
typeid( expression )
dataType 是数据类型,expression 是表达式,
type_info的成员函数:
a. name()返回类型的名称;
b. raw_name()用来返回名字编码;
c.hash_code()用来返回当前类型的函数值
(13)重载:
函数重载: 让一个函数名有多种功能; 可以在不同情况下进行不同的操作;
运算符重载:让一个运算符具有不同的功能;
运算符重载的格式:
返回值 operator 预算符名称(形参列表)
{
//函数体;
}
(14)运算符重载的规则:
a . 不是所有的都可以,大部分就可以重载:
不能重载的:
sizeof, 条件运算符?, 成员选择符. 对象选择符. * 域的解析符::
b. 重载不能改变运算符的优先级和结合性:
c1,c2,c3,c4
c4 =c1+c2*c3;
先执行c2*c3, 然后+c1 = c4;
c. 重载不会改变运算符的用法,
d. 不能有默认的参数,否则改变了运算符操作的个数。错误的。
e. 可以作为类的成员函数,也可以作为全局函数;
f. ->, [], (), =只能以成员函数的形式出现;
不对的例子:int operator + (int a,int b)
{
return (a-b);
}
+号原来是对两个数相加,现在企图通过重载使它的作用改为两个数相减,如果允许这样重载的话,那么表达式
4+3的结果是 7 还是 1, 所以不对,这是绝对禁止的。
(15)<< >> 重载:
输入运算符的重载>>
输入两个数,保存到复数对象A中:
istream & operateor >>(istream &in, complex &A)
{
cin>>A.m_real >>A.imag;
return cin;
}
istream 表示输入流,cin是istream类的对象;
输出运算符的重载<<
ostream &operator<<(ostream &out, complex &A)
{
cout <<A.m_read <<"+"<<A.m_imag<<"i";
return cout;
}
ostream:输出流, cout是ostream的类的对象;