继承与派生

C++学习笔记(三)

Posted by Chen Jinhao on July 13, 2021

继承与派生

1.各种派生类的比较
基类 公有成员 私有成员 保护成员
公有派生类 公有成员 不可访问成员 保护成员
私有派生类 私有成员 不可访问成员 私有成员
保护派生类 保护成员 不可访问成员 保护成员
2.同名成员的访问方式
class Base
{
    protected:
    int v1;
    public:
    int v2;
    Base(int a=0;int b=0)
    {
        v1=a;v2=b;
	}
};
class Derived:public Base
{
    int v2;
    public:
    int v3;
    Derived(int a=0,int b=0)
    {
        v2=a;v3=b;
	}
    void func()
    {
        //使用的是Derived中的v2
        int sum1=v1+v2+v3;
        //使用的是Base中的v2
        int sum2=v1+Base::v2+v3;
	}
}
3.赋值兼容原则

派生类对象可以赋值给基类对象,反过来会出现编译错误

class animal
{
    public:
    void eat()
    {
        cout<<"animal is eating"<<endl;
	}
};
class dog:public animal
{
    public:
    void eat()
    {
        cout<<"wang wang"<<endl;
	}
};
int main()
{
    animal a;
    dog d;
    d.eat();//输出"wang wang"
    a=d;//赋值成功,因为所有的狗都是动物,反过来则会出现编译错误
    a.eat();//"animal is eating"
    animal &ref_a=d;
    ref_a.eat();//"animai is eating"
    animal *pointer_a=&d;
    pointer_a->eat();//"animal is eating"
    return 0;
}
4.单继承下的构造函数与析构函数
class Circle
{
	Point center;//包含Point类的对象
    float radius;
    public:
    Circle(float x,float y,float r):center(x,y)
    {
        radius=r;
	}
};
class ColorCorclepublic Circle
{
    int color;
    public:
    ColorCircle(float x,float y,float r,int clolor):Circle(x,y,r)
    {
        this->color=color;
	}
};
  • 构造函数与析构函数的调用顺序正好相反
5.多继承派生类

(缺省的继承方式是private)

访问不同基类同名成员时的二义性

class A
{
	public:void f(){};
};
class B
{
    public:void f(){};
    void g(){};
};
class C:public A,public B
{
    public:g(){};
};
int main()
{
    C C1;
    C1.A::f();//通过类名对成员加以限定
    C1.B::f();
    
}

虚基类的使用

引入虚基类的目的是为了解决二义性问题,使公共基类在其派生类对象中只产生一个基类子对象

class A{};
class B1:virtual public A{};
class B2:virtual public A{};
class C:public B1,public B2{};

虚基类构造函数的调用顺序如下:

  • 虚基类的构造函数在非虚基类之前调用
  • 若在同一层次中包含多个虚基类,那么虚基类构造函数按它们说明的次序调用
  • 若虚基类由非虚基类派生,则遵守先调用基类构造函数,再调用派生类构造函数的规则