C++程序设计教程 第8讲:继承与派生(I
C++程序设计教程 第8讲:继承与派生 (II)
§7.4派生类的构造和析构函数 派生类的构造函数 基类的构造函数不被继承,派生类中需要声明 自己的构造函数。 声明构造函数时,只需要对本类中新增成员进 行初始化,对继承来的基类成员的初始化,自 动调用基类构造函数完成 (隐式调用) 派生类的构造函数需要给基类的构造函数传递 参数时,可以在构造函数中调用基类构造函数 (显式调用)
§7.4 派生类的构造和析构函数 派生类的构造函数 基类的构造函数不被继承,派生类中需要声明 自己的构造函数。 声明构造函数时,只需要对本类中新增成员进 行初始化,对继承来的基类成员的初始化,自 动调用基类构造函数完成。 (隐式调用) 派生类的构造函数需要给基类的构造函数传递 参数时,可以在构造函数中调用基类构造函数。 (显式调用)
§7.4派生类的构造和析构函数 显式调用 class poin七 I public Point (float =0.of, float =0.0f)i }; 派生类的声明 class Circle public Point Circle (float r=0.of, float x=0.Of, float y=0. of)i Circle:: Circle (float r, float a, float b) Point (a b) 派生类的实现
§7.4 派生类的构造和析构函数 显式调用: class Point { public: Point (float = 0.0f, float = 0.0f); … … }; class Circle : public Point { Circle (float r=0.0f, float x=0.0f, float y=0.0f); … … }; Circle::Circle (float r, float a, float b) : Point (a, b) { … … } 派生类的声明 派生类的实现
拷贝构造函数 若建立派生类对象时调用默认拷贝构造函数, 则编译器将自动调用基类的默认拷贝构造函数。 若编写派生类的拷贝构造函数,则需要为基类 相应的拷贝构造函数传递参数。例如 class base pub1ic:Base(){….}}; 调用Base的构造 class Derived: public Base 函数 public: Derived (Derived& d): Base(d)
拷贝构造函数 若建立派生类对象时调用默认拷贝构造函数, 则编译器将自动调用基类的默认拷贝构造函数。 若编写派生类的拷贝构造函数,则需要为基类 相应的拷贝构造函数传递参数。例如: class Base { public: Base() {…} }; class Derived : public Base { public: Derived (Derived& d) : Base(d) {…} }; 调用Base的构造 函数
侏承时的析构函数 析构函数也不被继承,派生类自行声明 声明方法与一般(无继承关系时)类的析 构函数相同。 不需要显式地调用基类的析构函数,系统 会自动隐式调用。 析构函数的调用次序与构造函数相反 如果是显式调用,必须用到虚函数( virtua)
继承时的析构函数 析构函数也不被继承,派生类自行声明 声明方法与一般(无继承关系时)类的析 构函数相同。 不需要显式地调用基类的析构函数,系统 会自动隐式调用。 析构函数的调用次序与构造函数相反。 如果是显式调用,必须用到虚函数(virtual)
把派生类对象隐式转换为基类对象 派生类对象能作为基类对象处理(即派生类对象指 针可强制转换成基类指针),反之不可! 例如:(引用写法) Derive d: Base&refB=d;//转成基类对象 /xefB只能作为Base对象看待 Derive&reED=refB;//转成派生类对象,OK! Base b: Derive&refD=b;//转成派生类对象,ERR!
把派生类对象隐式转换为基类对象 派生类对象能作为基类对象处理(即派生类对象指 针可强制转换成基类指针),反之不可! 例如: (引用写法) Derive d; Base& refB = d; // 转成基类对象 // refB 只能作为 Base 对象看待 Derive& refD = refB; // 转成派生类对象,OK! Base b; Derive& refD = b; // 转成派生类对象,ERR!
把派生类对象隐式转换为基类对象 派生类对象能作为基类对象处理(即派生类对象指 针可强制转换成基类指针),反之不可! 例如:(指针写法) Derive d: Base*pB=(Base*)&d;//转成基类对象的指针 /*pB只能作为Base对象看待 Derive*pD=( Derive*)pB;//转成派生类对象指针,oK! Base b: ● Derive*pD=( Derive*)b;//转成派生类对象指针
把派生类对象隐式转换为基类对象 派生类对象能作为基类对象处理(即派生类对象指 针可强制转换成基类指针),反之不可! 例如: (指针写法) Derive d; Base* pB = (Base*)&d; // 转成基类对象的指针 // *pB 只能作为 Base 对象看待 Derive* pD = (Derive*)pB; // 转成派生类对象指针,OK! Base b; Derive* pD = (Derive*)&b; //转成派生类对象指针,ERR!
把派生类对象隐式转换为基类对象 基类指针或对象与派生类指针或对象混合的四种可 能的方式: 直接用基类指针引用基类对象; 直接用派生类指针引用派生类的对象; 用基类指针引用一个派生类的对象; 用派生类指针引用基类的对象 基类 派生类指针 类指针 指针或引用转换,其内容不变! 派生类
把派生类对象隐式转换为基类对象 基类指针或对象与派生类指针或对象混合的四种可 能的方式: 1. 直接用基类指针引用基类对象; 2. 直接用派生类指针引用派生类的对象; 3. 用基类指针引用一个派生类的对象; 4. 用派生类指针引用基类的对象。 基 类 指 针 基类 派生类 派 生 类 指 针 指针或引用转换,其内容不变!
8复合与继承的比较 例 c1 ass BirthDa七e 构造的顺序是 class TelephoneNumber i.] 按指定顺序进 class Employee 行的! public Employee ( BirthDate birth;//作为Emp1oyee的成员 TelephoneNumber tel; };
§复合与继承的比较 例: class BirthDate { … }; class TelephoneNumber { … }; class Employee { public: Employee() { … } BirthDate birth; // 作为 Employee 的成员 TelephoneNumber tel; … }; 构造的顺序是 按指定顺序进 行的!
实例研究 class point i ●pub1ic: Point(f1oatx=0.0f,f1。aty=0.0f protected: float x, yi i class Circle public Point public: Circle (float r=0.Of, float x=0. of, float y=0. of)i float area consti protected: float radius; i class Cylinder public Circle i e public: Cylinder (float h=0. of, float r=o Of float x=0. Of, float y=0. of)i ●f1 oat area() const; e float volume const; e protected: float height J
实例研究 class Point { public: Point (float x=0.0f, float y=0.0f); protected: float x, y; }; class Circle : public Point { public: Circle (float r=0.0f, float x=0.0f, float y=0.0f); float area () const; protected: float radius; }; class Cylinder : public Circle { public: Cylinder (float h=0.0f,float r=0.0f, float x=0.0f, float y=0.0f); float area () const; float volume () const; protected: float height; };