C++继承基础

来源:互联网 发布:淘宝美工遇到的问题 编辑:程序博客网 时间:2024/05/18 13:30

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=1Derive构造函数,age=3Show, num:-842150451, age:3Base析构函数

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

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

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

原创粉丝点击