现在学继承,从基类继承的是派生类。
class derived:public base{
...;
}
公有继承时所有成员属性依旧相同,保护继承时基类的公有成员变为保护成员(对外封装对内公开),私有继承时全部成员变为私有成员。
基类指针和引用可以直接指向和引用派生类,这在函数形参中有很好的应用(实参使用派生类),但要注意只能使用基类的成员函数。也可以应用在定义基类指针数组具体元素指向基类或派生类。
派生类的构造函数会首先调用基类的构造函数。
derived(int a,char b):base(a){element=b;}
因为有引用和指针的多态性,所以在定义基类和继承类重名成员函数时可以定义为虚函数(在函数前加关键字virtual)。普通函数在面对多态调用时将根据形参对象决定使用哪个函数,而当使用虚函数时将根据实参对象决定。
需要注意在使用继承时最好定义虚析构函数,这样在使用多态的派生类时可以正确析构实参对象,否则将只析构形参对象。
尽管虚函数很好用,但是使用虚函数会牺牲运行效率和内存,所以默认还是使用普通函数。(虚函数必须使用动态联编)
虚函数属于隐藏而非重载,确定使用派生类函数时将会屏蔽基类函数。
/*****************************************************************************************************************************************/
当需要一个与两者都有一定共同点又不可共用的概念时(例如圆与椭圆),可以使用抽象基类,如下定义一个虚函数并=0即可定义,注意抽象类不能有具体对象只可用作基类。
virtual double area() const = 0;
定义这个抽象类之后便可用它的指针/引用来管理它的派生类,并可用于规范接口规则。
/****************************************************************************************************************************************/
当基类存在动态内存分配时且构造析构复制函数都编写无误,在派生类中不使用动态分配时无需任何特殊操作,派生类构造复制析构时都将自动调用基类的函数。
而当派生类也存在动态分配时,析构依然是自动调用,复制构造采用在初始化列表中调用基类复制构造函数(参数可仪直接用派生类对象),而赋值需要调用基类赋值函数
derived& operator =(const derived &d){
base::operator=(d);
...;
}
需要使用友元函数时(例如运算符重载<<),派生类如果想使用基类的该函数,又因为无法用作用域运算符限制,就只能使用强制类型转换来使用(将派生类转化为基类)。
今天的学习就到这里吧,效率好低。。。