2012-03-05
1、在类声明中声明的结构、类或枚举,作用域为整个类。此时不创建对象;若为private 权限,只能在类中使用被声明的类型;若public,则可在类外面使用被声明的类型
2、派生类的构造函数
(1)先创建基类对象→通过成员初始化列表将基类信息传给基类构造函数
(2)若不使用初始化列表,系统将调用基类的默认构造函数
(1)derived::derived(int x,int y):base(x,y)
{……}
(2)derived::derived(int x,int y)
{……}//此法调用基类的默认构造函数
析构的顺序相反,先析构派生类,再析构基类
3、基类指针可以指向派生类对象,基类引用可以引用派生类对象(无需类型转换)
但只能调用基类方法,不可用派生类的
4、多态:同一个方法在派生类和基类的行为不同,即方法的行为取决于调用该方法的对象
在基类中:virtual void func() 在派生类中: virtual void func()
当通过对象调用时,不加virtual也可;当通过指针或引用调用时,若不加virtual,程序根据引用或指针的类型选择方法,若加了virtual,程序根据引用或指针指向的对象的类型选择方法
例: Base s1; derived s2; base &p1=s1; base &p2=s2;
若不加virtual,p1.func与p2.func均调用base::func
若添加virtual,p1,func调用base的,p2.func调用derived的
注:同时为基类声明一个虚析构函数 virtual ~base();
用处:假设有多个实例,分别为base和derived类型,则不可用数组来存(类型不同),但可用一个指向base的指针数组,这些指针可以分别指向base或derived对象,此时就必须用虚函数——多态
5、动态、静态联编 向上、向下转换P447-P448
6、构造函数不能是虚函数,析构函数应当是虚函数,即使他不执行任何操作
eg:Base *p=new derived; delete p;
若不virtual,则只调用了base的析构,不会释放derived指向的内存;所以用虚函数,先析构derived(),再析构base();
另,给类定义一个虚拟析构函数,即使这个类不用做基类。
只有类成员才能是虚函数,友元不能是虚函数
7、A→B→C(箭头对应派生关系)
若C没有重新定义虚函数,用B的版本,若B没有定义,用A的版本
特例:若A:virtual void func(int a)const; //const表示不会修改内容
B:virtual void func() const;
特征标不一样时,将把A隐藏(而不是重载),此时B类不可以用A版本的函数
所以,(1)虚函数应保证特征标相同(返回值可以不一样)
(2)若A中func()有多个重载,则应在派生类中重新定义所有的基类版本
8、protected: A→B A中:protected int m;
对A而言,protected相当于private,对B而言,protected相当于public
∴数据成员最好不用protected,否则派生类对想可能会修改
2012-03-07
1、valarray类 include<valarray> //类比vector
double data[5]={1,2,3,4,5};
valarray<int > v1(8); //v1长度为8
valarray<int >v2(10,8); //8个10
valarray<double>v3(data,4); //以data 前四个初始化
2、class Student{
private: string name;
valarray<double>scores;
} //通过包含对象成员的类实现has a 关系(法一)
//成员函数可以使用string 和valarray的接口,但在类外不能用name.size()之类
//获得了实现,但没有继承接口 ∴这叫组合
3、使用explicit防止单参数构造函数的隐式转换
使用const限制方法修改数据
4、公有继承 is a 关系
私有继承 has a关系//获得实现,没有继承接口:类的公有方法成为派生类的私有方法
通过私有继承实现has a关系(法二)
class sutdent:private string,private valarray<double>
{……
}
访问基类方法:(类内)
对于法一,通过对象名来调用基类方法 | 对于法二,通过类名和作用域解析符调用方法 |
法一中,score.size(); | 法二中,只能用valarray<double>::size(); |
访问基类对象:强制类型转换
建议用包含(法一),而不是私有继承(法二),建立has a关系
5、共有多继承,来表示is a关系(必须显式声明为public,因为默认是private)
假设从上至下分别为类ABCD,继承关系如图
则当D d;时,d中包含2个A对象(一个B包含的,一个C包含的)
∴虚基类 从多个类(他们基类相同)派生出来的对象只继承一个基类对象
class B:virtual public A{……}
class C:virtual public A{……}
则class D:public B,public C{……}正确,当创建D类的对象时只会创建一次A
此时,D的构造函数将使用新规则
原规则:D(参数列表):B(a,b),C(a,b,){……} //错
新规则:D(参数列表):A(a),B(a,b),C(a,b){……} //显式的调用基类(虚基类)A
方法使用:
D d; d.show(); //错,不知道是用B的还是C的
法一: d.B::show();
法二:在D中重新定义show()
void D::show()
{ B::show();
}