zoukankan      html  css  js  c++  java
  • c++继承

    继承方式

    形式 public protected private
    public继承 public protected 不可见
    protected继承 protected protected 不可见
    private继承 private private 不可见

    :默认priavte

    知识点

    • 不可继承的函数:构造函数、拷赋值函数、析构函数
    • 虽然一般的运算符可以继承,但一般需要重写

    常用方法

    让派生类使用基类的友元函数

    #include <iostream>
    using namespace std;
    class base
    {
    private:
        int value = 90;
    public:
        friend ostream& operator<<(ostream &os,const base &a)
        {
            os << a.value << endl;
            return os;
        }
    };
    class derive:public base
    {
    private:
        int n = 100;
    public:
       friend ostream& operator<<(ostream &os,const derive &a)
        {
            os << (const base&)a;//强制转换为基类
            os << a.n << endl;
            return os;
        }
    };
    

    派生类的复制函数注意是否需要先复制基类

    class base
    {};
    class derive:public base
    {
    public:
        derive& operator=(const derive &b)
        {
            if(thie == &b)
                return *this;
            base::operator=(b);//先复制基类部分
            //复制本类
            return *this;
        }
    };
    

    使用using重新定义访问权限

    #include <iostream>
    #include <valarray>
    using namespace std;
    class student:private string,private valarray<double>
    {
    public:
        student(const string& s,double* a,int n):string(s),valarray<double>(a,n){}
        const string& name()const
        {
            return (const string &)*this;
        }
    /*     int sum()const
        {
            return valarray<double>::sum();
        }  */
        using valarray<int>::sum;
    };
    

    多继承(MI,Multi Inheritance)

    using namespace std;
    class Worker
    {
    private:
        string name;
    public:
        Worker(const string &s):name(s){}
        virtual void show()const =0;
    };
    class Singer:public Worker
    {
    private:
        int voice;
    public:
        Singer(const string &name,int _voice):Worker(name),voice(_voice){};
        virtual void show()const{}
    };
    class Waiter:public Worker
    {
    private:
        int panache;
    public:
        Waiter(const string &name,int _panache):Worker(name),panache(_panache){};
        virtual void show()const{}
    };
    class SingingWaiter:public Singer,public Waiter
    {
    private:
    public:
        SingingWaiter(const string &name,int _voice,int _panache):Singer(name,_voice),Waiter(name,_panache){}
    };
    

    指针易错

      SingingWaiter由Singer和Waiter派生,所以它有两个Worker,所以下面代码是错的,因为p指向的Worker不明确。

    SingingWaiter sw("name",5,4);
    Worker *p = &sw;
    

    正确的写法Worker *p = (Waiter*)&sw;Worker *p = (Singer*)&sw;

    同名方法

    由于SingingWaiter继承了来自Singer和Waiter中的show,所以它一共两个show,调用方法如下

    SingingWaiter a("name",4,5);
    a.show();//wrong
    a.Singer::show();//right
    a.Waiter::show();//right
    

    或者也可以自己重新定义SingingWaiter的show。

    虚基类

    虚基类使得多个类派生出的对象只继承一个基类对象。声明如下,让Singer和Waiter变成虚基类,也就是说SingingWorker只有一个Worker对象。

    using namespace std;
    class Worker
    {
    private:
        string name;
    public:
        Worker(){}
        Worker(const string &s):name(s){}
        virtual void show()const =0;
    };
    class Singer:virtual public Worker
    {
    private:
        int voice;
    public:
        Singer(const string &name,int _voice):Worker(name),voice(_voice){};
        virtual void show()const{}
    };
    class Waiter:virtual public Worker
    {
    private:
        int panache;
    public:
        Waiter(const string &name,int _panache):Worker(name),panache(_panache){};
        virtual void show()const{}
    };
    class SingingWaiter:public Singer,public Waiter
    {
    private:
    public:
        SingingWaiter(const string &name,int _voice,int _panache):Singer(name,_voice),Waiter(name,_panache){}
    };
    

    使用虚基类时,使用的是另一种新的构造方法。当基类是虚时,禁止信息通过中间类传递给基类,也就说,上面的构造函数SingingWaiter中,Singer(name,_voice)和Waiter(name,_panache)中的name不会传递给Worker,此时调用的时Worker的默认构造函数Worker()。

    如果需要显示地调用基类的构造函数,可以这样写:SingingWaiter(const string &name,int _voice,int _panache):Worker(name),Singer(name,_voice),Waiter(name,_panache){},当然这种写法在非虚基类是属于语法错误的。

  • 相关阅读:
    BZOJ2002 [HNOI2010] 弹飞绵羊
    BZOJ1030 [JSOI2007] 文本生成器
    BZOJ3233 [AHOI2013] 找硬币
    BZOJ4269 再见xor
    BZOJ5297 CQOI2018 社交网络
    LOJ149 0/1分数规划
    BZOJ2132 圈地计划
    UOJ131 [NOI2015] 品酒大会
    composer速度慢(composer更换国内镜像)
    thinkphp6安装报错,composer install tp6 报错 Parse error: syntax error
  • 原文地址:https://www.cnblogs.com/h-hg/p/8698585.html
Copyright © 2011-2022 走看看