继承与派生

Posted zhuzhudong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了继承与派生相关的知识,希望对你有一定的参考价值。

1、继承&派生

在定义一个新的类B时,若该类与某个已有的类A相似(B拥有A的全部特点),则可以将A作为一个基类,把B作为基类的一个派生类(子类)

在派生类的各个成员函数中,不能访问基类中的private成员。

class 派生类名:public 基类名
{
};

派生类对象的体积,等于基类对象的体积+派生类对象自己的成员变量的体积。

在派生类对象中,包含着基类对象,且基类对象的存储位置位于派生类对象新增的成员变量之前。

2、继承&复合

继承:“是”关系。

– 基类 A,B是基类A的派生类。

– 逻辑上要求:“一个B对象也是一个A对象”。

• 复合:“有”关系。

– 类C中“有”成员变量k,k是类D的对象,则C和D是复合关系

– 一般逻辑上要求:“D对象是C对象的固有属性或组成部分”。 

class CMaster; //CMaster必须提前声明,不能先写CMaster类后写Cdog类
class CDog {
 CMaster * pm;
};
class CMaster {
 CDog * dogs[10];
}; 

 

 3、访问范围说明符

(1)private:

可以被:基类的成员函数、基类的友元函数访问。

(2)public:

可以被:基类的成员函数、基类的友元函数、派生类的成员函数、派生类的友元函数、其它函数访问。

(3)protected

可以被:基类的成员函数、基类的友元函数访问,且派生类的成员函数可以访问当前对象的基类的保护成员。

class Father {
private: int nPrivate; //私有成员
public: int nPublic; //公有成员
protected: int nProtected; // 保护成员
};
class Son : public Father {
    void AccessFather () {
        nPublic = 1; // ok;
        nPrivate = 1; // wrong
        nProtected = 1; // OK, 访问从基类继承的protected成员
        Son f;
        f.nProtected = 1; //wrong, f不是当前对象
    }
};
int main(){
    Father f;
    Son s;
    f.nPublic = 1; // Ok
    s.nPublic = 1; // Ok
    f.nProtected = 1; // error
    f.nPrivate = 1; // error
    s.nProtected = 1; //error
    s.nPrivate = 1; // error
    return 0; 
}    

 

4、派生类的构造函数

(1)在执行派生类构造函数之前先执行基类构造函数。

构造函数名(形参表): 基类名(基类构造函数实参表)
{
}

 

显式方式: 派生类的构造函数中为基类的构造函数提供参数

derived::derived(arg_derived-list):base(arg_base-list)

 

隐式方式:派生类的构造函数中, 省略基类构造函数时,派生类的构造函数, 自动调用基类的默认构造函数

派生类的析构函数被执行时, 执行完派生类的析构函数后, 自动调用基类的析构函数。

(2)包含成员对象的派生类的构造函数

class Skill {
 public:
 Skill(int n) { }
};
class FlyBug: public Bug {
 int nWings;
 Skill sk1, sk2;
 public:
 FlyBug(int legs, int color, int wings);
};
FlyBug::FlyBug( int legs, int color, int wings):
Bug(legs, color), sk1(5), sk2(color) {
 nWings = wings;
}

 

创建派生类的对象时, 执行派生类的构造函数之前:

• 调用基类的构造函数,初始化派生类对象中从基类继承的成员

• 调用成员对象类的构造函数,初始化派生类对象中成员对象

• 执行完派生类的析构函数后:先调用成员对象类的析构函数,再调用基类的析构函数。析构函数的调用顺序与构造函数的调用顺序相反。

5、public继承的赋值兼容规则

class base { };
class derived : public base { };
base b;
derived d;

 

(1)派生类的对象可以赋值给基类对象

  b = d;

(2)派生类对象可以初始化基类的引用

  base &br = d;

(3)派生类对象的地址可以复制给基类指针

  base *pb = &d;

Note:若protected或private继承,则不成立。

6、直接基类与间接基类

声明派生类时,只需要列出其直接基类。

派生类的成员包括:派生类自己定义的成员,直接基类中的所有成员、所有间接基类里的全部成员。

#include <iostream>
using namespace std;
class Base {
public:
    int n;
    Base(int i):n(i) {
        cout << "Base " << n << " constructed" << endl;
    }
    ~Base() {
        cout << "Base " << n << " destructed" << endl;
    }
};
class Derived:public Base
{
public:
    Derived(int i):Base(i) {
        cout << "Derived constructed" << endl;
    }
    ~Derived() {
        cout << "Derived destructed" << endl;
    }
};
class MoreDerived:public Derived {
public:
    MoreDerived():Derived(4) {
       cout << "More Derived constructed" << endl;
    }
    ~MoreDerived() {
        cout << "More Derived destructed" << endl;
    }
};
int main()
{
    MoreDerived Obj;
    return 0;
}    

 

以上是关于继承与派生的主要内容,如果未能解决你的问题,请参考以下文章

继承与派生

继承与派生

类的继承与派生

面向对象之继承与派生

类的继承与派生

继承与派生知识点