一、基类指针
一般的,如果定义一个指向基类类型的指针,那么这种类型的指针具有如下特性:
- 指向基类对象的指针可以指向其子类对象。
- 如果子类覆盖了其基类中的函数成员,但通过基类指针所访问的成员仍然是基类的成员,而不是子类的成员。
比如基类BaseClass拥有函数F,其子类ChildClass中覆盖了函数F,那么如下语句将仍然调用A的函数F:
BaseClass *aptr; //基类类型的指针
ChildClass child;
aptr = &child; //仍可以指向子类对象
aptr->F(); //但仍然调用基类的函数F()二、多重继承
我的理解就是基类生子类,子类再生子类。
例如下面三个类构成一个继承链:
Millimeter继承自Centimeter,Centimeter又继承自Meter。
//基类
class Meter
{
private:
float dataMeter;
public:
void setData(float m)
{
dataMeter = m;
}
float getMeter(){return dataMeter;}
virtual float getData(){return dataMeter;}
float dataSquare(){return getData()*getData();}
};
//子类
class Centimeter:public Meter
{
private:
float dataCentimeter;
public:
//覆盖基类的setdata
void setData(float m)
{
dataCentimeter = m;
Meter::setData(dataCentimeter/10.0f);
}
float getCentimeter(){return dataCentimeter;}
virtual float getData(){return dataCentimeter;}
};
//测试多重继承
class Millimeter:public Centimeter
{
protected:
float dataMillimeter;
public:
void setData(float mi)
{
dataMillimeter = mi;
Centimeter::setData(dataMillimeter/10.0f);
}
float getMillimeter(){return dataMillimeter;}
virtual float getData(){return dataMillimeter;}
};因为两个子类都覆盖了setData函数,这时如果在主函数中执行下面的语句,将导致连锁的函数调用,每个类的中的数据成员都将被赋予相应的值:
Millimeter mm;
cout << "plesase input the mm:";
float temp;
cin>>temp;
mm.setData(temp); //导致连锁的函数调用,三、多继承
- 上述的继承链是继承的一种方式;
- 继承的另一种方式是多继承,在这种情况下,一个类有两个或多个父类。
- 但是多继承遭到很多程序设计人员的批评,并不建议在程序中使用多继承。并且Java语言也已经取消了多继承。单纯的继承链已经能够解决复杂的问题。
多继承的一般声明为:
class 子类名:继承修饰符 基类1,继承修饰符 基类2
比如:
class ChildClass:public BaseClass1,private BaseClass2注意:
- 多继承时的构造函数的调用顺序实在上面定义时就已经确定了。先调用基类1的构造,再调用基类2的,依次进行。
- 多继承可能会带来二义性。如果两个基类具有同名函数成员,那么子类中就需要对其进行覆盖,并通过作用域分辨符进行区分。
版权声明:本文为m0_37655357原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。