正在阅读:图例实解:C++中类的继承特性图例实解:C++中类的继承特性

2005-03-15 10:15 出处:PConline 作者:管宁 责任编辑:xietaoming


  但值得注意的是Vehicle(speed,total)的意义并不是对Vehicle类的个个成员的初始化,事实上是利用它创建了一个Vehicle类的无名对象,由于Car类对象的覆盖范围是覆盖于Vehicle类和Car类上,所以系统在确定了派生类对象a的空间范围后,确定了this指针位置,这个this指针指向了Vehicle类的那个无名对象,这个成员赋值过程就是,this->speed=无名对象.speed。

  其实这里概念比较模糊,笔者因为个人能力的原因暂时也无法说的更明确了,读者对此处知识点的学习,应该靠自己多对比多练习,进行体会理解。

  许多书籍对于派生类对象的复制这一知识点多是空缺的,为了教程的易读性,我还是决定说一下在复制过程中容易出错的地方,Car b=a;是派生类对象复制的语句,通过前面教程的学习我们我们知道,类对象的复制是通过拷贝构造函数来完成的,如果上面的例子我们没有提供拷贝构造函数不完整如下:

Car(Car &temp) 

    cout<<"载入Car类拷贝构造函数"<<endl; 
    Car::aird = temp.aird; 
}

  那么复制过程中就会丢失基类成员的数据了,所以Car类拷贝构造函数不能缺少Vehicle类无名对象的创建过程:Vehicle(temp.speed,temp.total),派生类对象的复制过程系统是不会再调用基类的拷贝构造函数的,this指针的问题再次在这里体现出来,大家可以尝试着把无名对象的创建去掉,观察b.speed的变化。

  类对象够创建必然就有析构过程,派生类对象的析构过程首先是调用派生类的析构过程,再调用基类的构造函数,正好和创建过程相反,在这里笔者已经在上面代码中加入了过程显示,读者可以自行编译后观察。

  最后我们说一下类的继承与组合

  其实类的组合我们在早些的前面的教程就已经接触过,只是在这里换了个说法而已,当一个类的成员是另一个类的对象的时候就叫做组合,事实上就是类于类的组合。组合和继承是有明显分别的,为了充分理解继承与组合的关系,我们在不破坏类的封装特性的情况下,先看如下的代码:

#include <iostream
using namespace std; 
 
class Vehicle 

public
    Vehicle(float speed=0,int total=0) 
    { 
        Vehicle::speed = speed; 
        Vehicle::total = total; 
    } 
protected
    float speed;//速度 
    int total;//最大载人量 
}; 
 
class Motor 

public
    Motor(char *motor) 
    { 
        Motor::motortype = motor; 
    } 
 
    char* SMT(Motor &temp); 
protected
    char *motortype;//发动机型号 
}; 
char* Motor::SMT(Motor &temp) 

    return temp.motortype; 

 
class Car:public Vehicle//继承的体现 

public
    Car(float speed,int total,int aird,char *motortype):Vehicle(speed,total),motor(motortype) 
    { 
        Car::aird = aird; 
    } 
 
    Motor rm(Car &temp); 
protected
    int aird;//排量 
    Motor motor;//类组合的体现 
}; 
 
Motor Car::rm(Car &temp) 

    return temp.motor; 

 
//-------------------------------------------------------------- 
void test1(Vehicle &temp) 

    //中间过程省略 
}; 
void test2(Motor &temp) 

    cout<<temp.SMT(temp);//读者这里注意一下,temp既是对象也是对象方法的形参 

//-------------------------------------------------------------- 
 
void main() 

    Car a(150,4,250,"奥地利AVL V8"); 
    test1(a); 
    //test2(a);//错误,Car类与Motor类无任何继承关系 
    test2(a.rm(a));//如果Car类成员是public的那么可以使用test2(a.motor) 
    cin.get(); 
}

  在上面的代码中我们新增加了发动机类Motor,Car类增加了Motor类型的motor成员,这就是组合,拥有继承特性的派生类可以操作基类的任何成员,但对于与派生类组合起来的普通类对象来说,它是不会和基类有任何联系的。 

  函数调用:test1(a);,可以成功执行的原因就是因为Car类对象在系统是看来一个Vehicle类对象,即Car类是Vehicle类的一种Car类的覆盖范围包含了Vehicle

  函数调用:test2(a);,执行错误的原因是因为Motor类并不认可Car类对象a与它有任何关系,但我们可以通过使用Car类对象a的Motor类成员motor,作为函数形参的方式来调用test2函数(test2(a.motor)),在这里由于类的成员是受保护的所以我们利用a.rm(a)来返回受保护的motor,作为函数参数进行调用。

键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品