C++继承基础

C++中的继承分为三种继承方式:
public,protected,private。
继承会导致父类中的成员访问属性发生变化。

继承机制中,子类访问父类成员方式
不管什么继承,父类的private成员始终为父类私有。
public继承:父类的public和protected成员在子类中访问属性不变
private继承:父类的public和protected成员在子类中变成private
protected继承:父类public和protected成员在子类中变成protected

例子1:

class Base{
public:
    Base()
    {
        printf("Base构造函数\n");
    }

    ~Base()
    {
        printf("Base析构函数\n");
    }
};

class Derive : public Base{
public:
    Derive()
    {
        printf("Derive构造函数\n");
    }

    ~Derive()
    {
        printf("Derive析构函数\n");
    }
};

int main()
{
    Base* d = new Derive();
    delete d;
    return 0;
}

这段代码输出:

Base构造函数
Derive构造函数
Base析构函数

分析:
主函数中Base* d = new Derive(),new一个Base类型的指针实例。
因为子类是继承父类的,所以调用子类的构造方法之前,必然会首先调用父类的构造方法(初始化父类的一些成员变量);
new出来的实例是Base类型的,所以delete时,会调用Base的析构函数。

例子2:

将例1中的主函数变为:

Derive* d = new Derive();
delete d;

输出:

Base构造函数
Derive构造函数
Derive析构函数
Base析构函数

分析:
构造函数的调用顺序与例1一样,不同的是这次new出来的实例指向了Derive类型的指针,因为Derive继承了Base类中成员变量和函数,所以生成Derive类型实例的同时,必然会产生Base类型的实例。
根据析构函数的调用顺序,先构造后析构,因此输出结果如上。

例子3:

将例1中Base的析构函数改为virtual函数:

virtual ~Base()
{
    printf("Base析构函数\n");
}

输出结果:

Base构造函数
Derive构造函数
Derive析构函数
Base析构函数

可以看出,输出结果与例2一样。
构造函数的调用顺序与上面的例子一样,这次因为Base的析构函数成了虚函数,父类指针指向子类的实例,所以在调用父类的析构函数时,会有多态效果,实际调用的是子类的析构函数。
delete d的时候,先析构继承类,再析构父类。

实际上,我们在使用类的析构函数时,一般都把析构函数设为虚函数。
在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。

例子4:

class Base{
public:
    Base(int num)
    {
        num_ = num;
        printf("Base构造函数,num=%d\n", num_);
    }

    ~Base()
    {
        printf("Base析构函数\n");
    }

    virtual void Show()
    {
        printf("Show:%d\n",num_);
    }

protected:
    int num_;
};

class Derive : public Base{
public:
    Derive(int num, int age):Base(num)
    {
        age_ = age;
        printf("Derive构造函数,age=%d\n", age_);
    }

    ~Derive()
    {
        printf("Derive析构函数\n");
    }

    void Show()
    {
        printf("Show, num:%d, age:%d\n", num_, age_);
    }

private:
    int age_;
    int num_;
};

int main()
{
    Base* d = new Derive(1,3);
    d->Show();
    delete d;
    return 0;
}

输出:

Base构造函数,num=1
Derive构造函数,age=3
Show, num:-842150451, age:3
Base析构函数

子类的成员变量和函数名是可以跟父类相同的。
继承类的构造函数需要“继承”基类的构造函数,因为在构造子类时,必然要构造基类。
用:符号来“继承”。
如:Derive(int num, int age):Base(num)

当继承类的成员变量名与基类相同时,以继承类为准。

当基类的成员函数修饰为virtual函数时,指向基类的继承类实例调用函数时,调用的是继承类的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值