精华内容
下载资源
问答
  • c++派生类
    2022-04-16 20:35:52

    1.整体构造顺序

    前面我们提到过,一个类在构造的时候,先会构造其成员变量,在调用自身的构造函数。

    对于派生类来说,除了可能有成员变量,还可能有多个基类。在初始化派生类对象时,其构造函数要负责基类与基类成员对象的构造,还要负责自己成员对象的构造。

    2.构造格式

    前面也提到过,派生类只能使用构造函数初始化列表的方式,向基类与成员变量的构造函数传递参数完成初始化工作。具体形式如下:
    派生类构造函数(args):基类构造函数(args),成员对象1(args),成员对象2(args),…

    派生类对象构造的顺序为:
    1.先构造基类
    2.再构造自身成员变量
    3.最后调用自身构造函数

    基类构造顺序由派生层次决定:最远的基类最先构造 成员构造顺序和定义顺序符合。
    而析构函数的析构顺序与构造顺序相反。

    3.派生类构造顺序实习

    #include<iostream>
    using namespace std;
    
    class A {
        int a;
        public:
            A(int a=0) {
                this->a = a;
                cout<<"a is: "<<this->a<<endl;
            }
    };
    
    class B {
        int b;
        public:
            B(int b) {
                this->b = b;
                cout<<"b is: "<<this->b<<endl;
            }
    };
    
    class C {
        int c;
        public:
            C(int c) {
                this->c = c;
                cout<<"c is: "<<this->c<<endl;
            }
    };
    
    class D {
        int d;
        public:
            D(int d) {
                this->d = d;
                cout<<"d is: "<<this->d<<endl;
            }
    };
    
    class E : public B, public D {
        public:
            C c1, c2;
            A *a1 = new A(10);
            A a2, a3;
            E(): a2(2), a3(3), c1(11), c2(22), B(100), D(200) {
                cout<<"d is init!"<<endl;
            }
    };
    
    int main(int argc, char const *argv[])
    {
        E e;
        return 0;
    }
    

    代码输出结果:

    b is: 100
    d is: 200
    c is: 11
    c is: 22
    a is: 10
    a is: 2
    a is: 3
    d is init!
    

    根据上面代码输出结果,再结合第二部分内容,不难看出派生类的实际构造顺序。

    4.派生类析构顺序实例

    #include<iostream>
    #include<string>
    using namespace std;
    
    class A {
        public:
            virtual ~A() { cout<<"call A::~A()"<<endl; }
    };
    
    class B: public A {
         char *c;
         public:
            B(int i) {c = new char[i];}
            ~B() {
                delete [] c;
                cout<<"call B::~()"<<endl;
            }
    };
    
    int main(int argc, char const *argv[])
    {
        A *a = new B(10);
        delete a;
        return 0;
    }
    

    代码运行结果为:

    call B::~()
    call A::~A()
    
    更多相关内容
  • c++ 派生类

    千次阅读 2022-04-06 13:42:42
    1.派生类是对类的具体化,而类是派生类的抽象。 2.派生类的声明方式:class 派生类名 继承方式 基类名。 3.派生类的继承方式有protected private public。 4.公用继承的介绍: 代码示例如下: #include<iostream&...

    1.派生类是对类的具体化,而类是派生类的抽象。
    2.派生类的声明方式:class 派生类名 继承方式 基类名。
    3.派生类的继承方式有protected private public。
    4.公用继承的介绍:
    代码示例如下:

    #include<iostream>
    #include<string>
    using namespace std;
    class Student//声明基类
    {
    public:
        void get_1()//输入姓名及性别
        {
            cin >> name >> sex;
        }
        void display_1()//输出姓名性别
        {
            cout << "姓名:" << name << " " << "性别:" << sex << endl;
        }
    private:
        string sex;
        string name;
    };
    class Student1 :public Student//声明派生类,继承方式为public
    {
    public:
        void get_2()//输入成绩学号
        {
            cin >> score >> num;
        }
        void display_2()//输出成绩学号
        {
            cout << "成绩:" << score << " " << "学号:" << num << endl;
        }
    private:
        int score;
        int num;
    };
    int main()
    {
        Student1 s;//定义派生类对象
        s.get_1();
        s.get_2();
        s.display_1();
        s.display_2();
        return 0;
    }
    

    代码还可以更优化如下:

    #include<iostream>
    #include<string>
    using namespace std;
    class Student//声明基类
    {
    public:
        void get_1()//输入姓名及性别
        {
            cin >> name >> sex;
        }
        void display_1()//输出姓名性别
        {
            cout << "姓名:" << name << " " << "性别:" << sex << endl;
        }
    private:
        string sex;
        string name;
    };
    class Student1 :public Student//声明派生类,继承方式为public
    {
    public:
        void get_2()//输入成绩学号以及姓名性别
        {
            get_1();//在派生类中调用基类的get_1函数
            cin >> score >> num;
        }
        void display_2()//输出成绩学号以及姓名性别
        {
         display_1();//在派生类中调用基类的display_1函数
            cout << "成绩:" << score << " " << "学号:" << num << endl;
        }
    private:
        int score;
        int num;
    };
    int main()
    {
        Student1 s;//定义派生类对象
        s.get_2();
        s.display_2();
        return 0;
    }
    

    面向对象程序设计
      面向对象程序设计(OOP)的核心思想是数据抽象、 继承和动态绑定。

    使用数据抽象, 我们可以将类的接口与实现分离(封装)。
    使用继承, 我们可以定义相似的类型并对其相似关系建模。
    使用动态绑定, 可以在一定程度上忽略相似类型的区别, 而以统一的方式使用它们的对象(多态)
    类之间的关系
      类之间的三种关系:

    • 包含关系(has-A)
    class B{ private: A a;}
    
    • 使用关系(uses-A)
    class B{public: void method(A &a);}
    
    • 继承关系(is-A)
    class B: public A{}
    

    继承的概念
      继承: 通过继承联系在一起的类构成一种层次关系。

    • 通常在层次关系的根部有一个基类, 也称为父类。
    • 其他类直接或间接地从基类继承而来, 这些继承得到的类称为派生类, 也称为子类。
    • 基类负责定义在层次关系中所有类共同拥有的成员, 而每个派生类定义各自特有的成员。

    继承关系示例
    在这里插入图片描述
    继承具有传递性, U3D程序员、 UE程序员、 Java程序员都属于程序员。
    继承不具有对称性, 不是所有的程序员都是U3D程序员。
    基类是对派生类的抽象, 派生类是对基类的具体化。

    派生类的定义
      定义派生类的一般形式:

    class 派生类名:类派生列表
    {
    成员列表
    }
    

    注意:
    除了增加基类列表外, 派生类的定义与类的定义并无区别。
    派生类的成员列表描述的是派生类自己新增加的数据成员和成员函数。
    类派生列表指定了一个或多个基类, 由访问说明符和基类的名称构成。

    class Derived : public Base1, public Base2
    {
    成员列表
    }
    

    派生类的构成
    在这里插入图片描述
    派生类拥有基类所有的数据成员和成员函数。
    派生类可以拥有基类没有的数据成员和成员函数。
    可以通过访问说明符控制成员的访问权限。
    可以通过在派生类中声明同名的成员, 来实现修改基类成员功能的效果。
    派生类是一种特殊的基类, 可以将派生类对象当作父类对象使用。
    友元函数不能被继承, 友元函数不是成员函数。

    #include<iostream>
    
    using namespace std;
    
    //基类, 拥有2个数据成员和一个成员方法
    class Base
    {
    public:
        int bnum1_;
        int bnum2_;
    
        void print()
        {
            cout << "Base" << endl;
            cout <<" bnum1_ :" << bnum1_ << " bnum2_ :" << bnum2_ << endl;
        }
    };
    
    //派生类,继承自Base
    class Derived : public Base
    {
    public:
        int dnum_; //派生类中新增加的数据成员
    
        void print() //同名函数,可以修改基类中同名的函数的功能
        {
            cout << "Derived" << endl;
            cout << " bnum1_ :" << bnum1_ << " bnum2_ :" << bnum2_ << "dnum_ :" << dnum_ << endl;
        }
    };
    
    int main()
    {
        Base b1;
        b1.bnum1_ = 10;
        b1.bnum2_ = 20;
    
        Derived d1;
        d1.bnum1_ = 10;
        d1.bnum2_ = 30;
        d1.dnum_ = 5;
    
        b1.print();
        d1.print();
        d1.Base::print(); //如果想要调用基类中的方法,可以使用作用域操作符::
        return 0;
    }
    
    
    

    派生类的访问控制
    单个类的访问控制:
    public(公有成员): 在类的内部和外部都可以访问的成员。
    private(私有成员): 在类的内部可以访问, 在类的外部不可以访问, 只能通过成员函数或友元函数进行访问。
    protected(保护成员) : 与私有成员类似, 但在派生类中可以访问。

    在派生类内部(成员函数或友元函数)使用基类成员时: 不受继承方式的影响, 只看该成员在基类中的访问属性。
    在这里插入图片描述
    在派生类外部(派生类用户)使用基类成员时: 不同的继承方式决定了基类成员在派生类中的访问属性, 从而对派生类用户的访问权限产生影响。

    public继承, 所有基类成员在派生类中保持原有的访问级别。

    protected继承, public–protected, protected-protected,private-private。
    private继承, 所有基类成员在派生类中变为private成员。
    在这里插入图片描述

    #include<iostream>
    
    using namespace std;
    
    class Base
    {
    public:
        int bnum1_;
    private:
        int bnum2_;
    protected:
        int bnum3_;
    
    public:
        //在类的内部,都可以访问到,通过成员方法,或者是友元函数
        void setNum(int bnum1, int bnum2, int bnum3)
        {
            bnum1_ = bnum1;
            bnum2_ = bnum2;
            bnum3_ = bnum3;
        }
        friend void print(Base &b)
        {
            cout << b.bnum1_ << " " << b.bnum2_ << " " << b.bnum3_ << endl;
        }
    };
    
    class Derived : public Base
    {
    public:
        int dnum1_;
    private:
        int dnum2_;
    protected:
        int dnum3_;
    
    public:
        //在派生类内部只能访问到基类的public成员和protected成员,不能访问基类的private成员。
        //不看派生类的继承方式
        void setNum(int dnum1, int dnum2, int dnum3)
        {
            dnum1_ = dnum1;
            dnum2_ = dnum2;
            dnum3_ = dnum3;
        }
        friend void printD(Derived &d)
        {
            d.bnum1_ = 10;
            //d.bnum2_ = 17;//基类的私有成员,在派生类中不可以访问
            d.bnum3_ = 15;
    
            cout << d.dnum1_ << " " << d.dnum2_ << " " << d.dnum3_ << endl;
        }
    
    };
    
    class Derived1 : private Base
    {
    public:
        void print()
        {
            //bnum2_ = 10; //基类的私有成员,在派生类中不可以访问
            cout << bnum1_ << " " << bnum3_ << endl; //基类的公有成员和保护成员,在派生类中可以访问
        }
    };
    
    class Derived2 : protected Base
    {
    public:
        void print()
        {
            //bnum2_ = 10; //基类的私有成员,在派生类中不可以访问
            cout << bnum1_ << " " << bnum3_ << endl; //基类的公有成员和保护成员,在派生类中可以访问
        }
    };
    
    int main()
    {
        Base b;
        b.bnum1_ = 10;
        //b.bnum2_ = 10;  //在类的外部不可以访问,private
        //b.bnum3_ = 15;  //在类的外部不可以访问,protected
    
        b.setNum(14, 16, 17);
        print(b);
    
        //在派生类的外部访问基类中的成员时,会根据继承方式影响基类成员的访问级别
        //1.public 继承
        Derived d;
        d.bnum1_ = 10; //public - public, 可以被访问
        //d.bnum2_ = 15; //private -- private ,不可以被访问
        //d.bnum3_ = 10; //protected -- protected, 不可以被访问
    
        //2.private 继承
        Derived1 d1;
        //d1.bnum1_ = 15; //public -- private,不可以被访问
        //d1.bnum2_ = 10; //private -- private, 不可以被访问
        //d1.bnum3_ = 20; //protected -- private, 不可以被访问
    
        //3.protected 继承
        Derived2 d2;
        //d2.bnum1_ = 10; //public -- protected,不可以被访问
        //d2.bnum2_ = 16; //private -- private, 不可以被访问
        //d2.bnum3_ = 9; //protected -- protected,不可以被访问
        return 0;
    }
    
    

    访问属性设置的原则:
    需要被外界访问的成员, 设置为: public。
    只能在当前类中访问的成员, 设置为: private。
    只能在当前类和派生类中访问的成员, 设置为: protected。

    展开全文
  • C++派生类

    千次阅读 2022-02-09 10:35:43
    学习笔记:C++派生类

    从一个类派生出的另一个类称为派生类,原始的类为基类。先有基类。

    假如 player是基类

    class player

    {

    private:

    ...

    public:

    ...

    };

    从 player 类派生出类 rateplayer 表示为

    class rateplayer : public player

    {

    ...

    };

    关键词 public 表明这是一个公有派生。使用公有派生,基类的公有成员成为派生类的公有成员;基类的私有部分也成为派生类的一部分,但只能通过基类的公有方法(public)和保护方法(protected)访问。

    (私有继承使用关键词 private, 使用私有继承,基类的公有方法将成为派生类的私有方法)

    上述代码(class rateplayer : public player)完成的工作:

    1. 派生类对象存储基类的数据成员;

    2. 派生类对象可以使用基类的方法;

    派生类需要自己完成 的工作:

    3. 需要自己的构造函数;

    4. 添加自己的成员和方法。

    构造函数

    派生类构造函数必须使用基类构造函数。创建派生类对象时,程序首先创建基类对象。下面是一个派生类构造函数的例子:

    rateplayer :: rateplayer(unsigned int r, const char * fn, const car * ln, bool ht) : player (fn, ln, ht)

    {

    }

    使用声明

    rateplayer rplayer1 ( 1000, “Mallory”,“Duck”, true) ;

    rateplayer 把参数 “Mallory”,“Duck”, true赋给形参 fn, ln, ht ,调用基类的构造函数

     player (fn, ln, ht), 创建一个player 对象, 然后进入rateplayer的函数实体中,完成其它成员的初始化。

    如果不调用基类的构造函数,程序将使用默认的构造函数来创建基类对象。

    rateplayer :: rateplayer(unsigned int r, const char * fn, const car * ln, bool ht) 

    {

    }

    等同于:

    rateplayer :: rateplayer(unsigned int r, const char * fn, const car * ln, bool ht) : player ()

    {

    }

    析构函数

    释放对象的顺序和创建对象的顺序相反,先执行派生类的析构函数,再执行基类的析构函数。

    派生类和基类的关系

    1. 派生类可以使用基类的方法;

    2. 基类指针可以指向派生类对象,基类引用可以引用派生类对象;可以将派生类对象赋给基类引用或基类指针的形参;

    3. 基类指针或引用只能使用基类的方法,不能使用派生类的方法(非基类方法);

    4. 不可以将基类对象的地址赋给派生类的引用和指针;

    如果将基类对象赋给派生类的引用,派生类引用就能够为基类对象调用派生类的方法,这是不允许的(基类对象只能使用基类的方法,不能使用派生类的方法);

    相反,将派生类对象赋给基类的引用是可以的,因为派生类对象可以使用基类的方法。

    5. 将派生类对象赋给基类对象,等同于将将派生类对象中基类的成员赋给基类。

    例如代码

    rateplayer olaf1 (1840, "Olaf", "Loaf", true);

    player olaf2(olaf1);

    初始化 olaf2 所匹配的构造函数为 player (const  rateplayer &),但没有定义这样的函数,使用基类的构造函数

    player (const  player &);

    进行创建,将 rateplayer 对象赋给 player &,将olaf1中的基类的部分复制给基类的对象。

    C++ Primer Plus

    展开全文
  • 基类与派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类的值赋给基类对象,在用到基类对象的时候可以用其子类对象代替。 具体表现在以下几个方面: 派生类对象可以向基类对象赋值...
  • protected 与 public 和 private 一样是用来声明成员的访问权限的。由protected声明的成员...在定义一个派生类时将基类的继承方式指定为protected的,称为保护继承,用保护继承方式建立的派生类称为保护派生类(protec
  • c++派生类例子

    2014-06-07 20:51:13
    派生类例子输入几个几何图形的体积在主函数用指向数组的指针输出
  • C++派生类与继承

    2022-02-17 14:15:57
    继承和派生其实都是一回事,只是说法不同罢了。 如:子类继承了父类,父类派生了子类。 那么什么是继承呢 首先,如上图所示是一个动物种类区分图。猫和狗都属于动物这一种类,而猫又可以细分为加菲猫、布偶猫等...

            继承和派生其实都是一回事,只是说法不同罢了。
            如:子类继承了父类,父类派生了子类。

    那么什么是继承呢

            首先,如上图所示是一个动物种类区分图。猫和狗都属于动物这一种类,而猫又可以细分为加菲猫、布偶猫等种类。我们发现这些细分出来的单体在拥有上一级别的共性之外,还有各自的共性。比如加菲猫和布偶猫体型、毛发品质不同,但他们都属于猫类。
            在编写代码的时候类与类之间也一样,子类拥有上一级类的共性,又拥有自己的特性!这个时候就可以利用继承的特性减少代码的重复性!!

    一、基类 & 派生类

            当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类

            例如我们看到很多网站中,都有公共的头部,公共的底部,甚至公共的左侧列表,只有中心内容不同。

    #include <iostream>
    using namespace std;
    
    //基类
    class basepage {
    	public:
    		void header()
    		{
    			cout << "首页、公开课、登录、注册...(公共头部)" << endl;
    		}
    		void footer()
    		{
    			cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
    		}
    		void left()
    		{
    			cout << "Java,Python,C++...(公共分类列表)" << endl;
    		}
    };
    
    //派生类
    class CPP :public basepage {
    public:
    	void content() {
    		cout << "C++学科视频" << endl;
    	}
    };
    
    void test01()
    {
    	//C++页面
    	cout << "C++下载视频页面如下: " << endl;
    	CPP cp;
    	cp.header();
    	cp.footer();
    	cp.left();
    	cp.content();
    }
    
    int main() {
    	test01();
    	system("pause");
    	return 0;
    }
    
    
    

            运行结果:

             从运行结果可以看出,CPP类在定义自己的特性基础上还保留basepage类的属性,这就是派生的基本用法。

            一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:

    class 派生类名:继承方式 基类名

            其中继承属性有public、private、protected三种 。

    多继承的方式如下:

            语法:class 派生类:继承方式 基类1 ,继承方式 基类2

    二、继承方式

            前面说了类的继承方式有三种public、private、protected,他们的区别就是派生类对基类的访问权限有所不同!

    • 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有保护成员来访问。
    • 保护继承(protected): 当一个类派生自保护基类时,基类的公有保护成员将成为派生类的保护成员。
    • 私有继承(private):当一个类派生自私有基类时,基类的公有保护成员将成为派生类的私有成员。

            代码如下:

    #include <iostream>
    using namespace std;
    
    //
    //**继承方式一共有三种:**
    //
    //* 公共继承
    //* 保护继承
    //* 私有继承
    
    class base1 {
    public:
    	int m_a;
    protected:
    	int m_b;
    private:
    	int m_c;
    };
    
    //公有派生
    class son1 :public base1 {
    public:
    	void func() {
    		m_a;	//可访问public权限
    		m_b;	//可访问protected权限
    		//m_c;	//m_c是基类的私有权限无法访问
    	}
    };
    
    //保护派生
    class son2 :protected base1 {
    public:
    	void func() {
    		m_a;	//可访问protected权限
    		m_b;	//可访问protected权限
    		//m_c;	//m_c是基类的私有权限无法访问
    	}
    };
    
    //保护派生
    class son3 :private base1 {
    public:
    	void func() {
    		//m_a;	//不可访问private权限
    		//m_b;	//不可访问private权限
    		//m_c;	//m_c是基类的私有权限无法访问
    	}
    };
    
    
    void test() {
    	son1 s;
    	s.m_a;
    	//s.m_b; 公有派生不改变成员变量的权限,因此m_b是保护权限,类外无法访问
    
    	son2 s1;
    	//s1.m_a;	//protected权限,类外无法访问
    }
    
    int main()
    {
    	system("pause");
    	return 0;
    }

    三、继承的对象模型

            从父类继承过来的成员变量,哪些属于子类对象中?我们已经知道当发生公有继承的时候,不会改变基类成员变量的访问权限。
            并且在派生类中,无法访问基类中private属性的成员变量。无法访问并不意味着没有继承到派生对象中。可以看到如下代码:

    #include <iostream>
    using namespace std;
    
    //基类
    class base {
    public:
    	int m_a;
    protected:
    	int m_b;
    private:
    	int m_c;
    };
    
    class son1 :private base {
    public:
    	int m_d;
    };
    
    void test() {
    	cout << "son1 的 size = " << sizeof(son1) << endl;
    }
    
    int main()
    {
    	test();
    	system("pause");
    	return 0;
    }

     运行结果:

             可以看出类son1的大小有16个字节,可以得出结论:派生类会继承基类中的private权限的成员变量。

            一个派生类继承了所有的基类方法,但如下三种情况除外:

    • 基类的构造函数、析构函数和拷贝构造函数。
    • 基类的重载运算符。
    • 基类的友元函数。

    四、基类和派生类构造/析构函数执行的顺序

            

    #include <iostream>
    using namespace std;
    
    class base {
    public:
    	base() {
    		cout << "base构造函数" << endl;
    	}
    	~base() {
    		cout << "base析构函数" << endl;
    	}
    };
    
    class son :public base {
    public:
    	son() {
    		cout << "son构造函数" << endl;
    	}
    
    	~son() {
    		cout << "son析构函数" << endl;
    	}
    };
    
    void test() {
    	son b1;
    }
    
    int main()
    {
    	test();
    	system("pause");
    	return 0;
    }
    

    运行结果:

            从运行结果可以看出在派生中,先执行基类的构造函数,再执行派生类的构造函数(肯定现有爸爸,才有儿子嘛)。析构函数顺序则与前者相反!

    五、同名成员变量(函数)的处理

            有时候我们会遇到派生类和基类出现同名成员函数和成员变量的问题,这时派生类会隐藏基类类中所有版本的同名成员函数。
            即在派生类定义的对象中访问同名成员变量(函数)的时候,执行的是派生类中。如果想访问基类中的成员变量(函数),就需要基类作用域。

    #include <iostream>
    using namespace std;
    
    class base {
    public:
    	base() {
    		m_a = 100;
    	}
    	void func() {
    		cout << "base -func()的调用" << endl;
    	}
    
    	void func(int a) {
    		cout << "base -func(int a)的调用" << endl;
    	}
    public:
    	int m_a;
    };
    
    class son :public base {
    public:
    	son() {
    		m_a = 200;
    	}
    
    	//当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
    	//如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
    	void func()
    	{
    		cout << "Son - func()调用" << endl;
    	}
    
    public:
    	int m_a;
    };
    
    void test01() {
    	son s;
    
    	cout << "son下的 m_a:" << s.m_a << endl;
    	cout << "base下的 m_a:" << s.base::m_a << endl;
    
    	s.func();
    	s.base::func();
    	s.base::func(10);
    }
    
    int main()
    {
    	test01();
    	system("pause");
    	return 0;
    }

    运行结果:

     六、同名静态成员变量(函数)的处理

            除了遇到同名成员变量(函数),有时还会遇到同名的静态成员变量(函数)。与前者相似,为了访问基类的同名对象,需要加上作用域。只不过静态成员变量(函数)有两种访问方式:

            ①通过对象访问
            ②通过类名访问

    #include <iostream>
    using namespace std;
    
    class base {
    
    public:
    	static void func() {
    		cout << "base static void func()" << endl;
    	}
    	static void func(int a) {
    		cout << "base static void func(int a)" << endl;
    	}
    
    public:
    	static int m_a;
    };
    
    int base::m_a = 10;	/*类的静态成员变量,类内声明,类外定义*/
    
    class son:public base {
    public:
    	static void func() {
    		cout << "son static void func()" << endl;
    	}
    
    public:
    	static int m_a;
    };
    
    int son::m_a = 20;
    
    //同名静态成员属性
    void test01() {
    	//通过对象访问
    	cout << "通过对象访问" << endl;
    	son s1;
    	cout << "son 下的m_a:" << s1.m_a << endl;
    	cout << "base 下的m_a:" << s1.base::m_a << endl;
    
    	//静态成员变量可以通过类名进行访问
    	cout << "通过类名进行访问" << endl;
    	cout << "son 下的m_a:" << son::m_a << endl;
    	cout << "base 下的m_a:" << son::base::m_a << endl;
    }
    
    //同名静态成员函数
    void test02() {
    	//通过对象访问
    	cout << "通过对象访问静态同名成员函数" << endl;
    	son s2;
    	s2.func();
    	s2.base::func();
    
    	//通过类名访问
    	son::func();
    	son::base::func();
    	son::base::func(10);
    }
    
    int main()
    {
    	test01();
    	test02();
    	system("pause");
    	return 0;
    }

    运行结果:

     七、菱形继承问题

            菱形继承,虚继承_audience_fzn的博客-CSDN博客

            两个派生类继承同一个基类,又有某个类同时继承两个派生类这种继承被称为菱形继承。这个时候,就会发生数据的二义性

            因为最后的类继承了2次,原始基类的特性。为了解决这种情况引入了virtual关键字。代码如下:

    #include <iostream>
    using namespace std;
    
    class animal {
    public:
    	int m_age;
    
    };
    
    //sheep继承animal
    class sheep:virtual public animal {
    
    };
    
    class Tuo:virtual public animal {
    
    };
    
    class sheepTuo:public sheep, public Tuo {
    
    };
    
    void test01() {
    	sheepTuo s;
    	s.sheep::m_age = 100;
    	s.Tuo::m_age = 200;
    	cout << "s.sheep::m_age=" << s.sheep::m_age << endl;
    	cout << "s.Tuo::m_age=" << s.Tuo::m_age << endl;
    }
    
    int main()
    {
    
    	test01();
    	system("pause");
    	return 0;
    }

            继承前加virtual关键字后,变为虚继承。此时公共的父类Animal称为虚基类

    运行结果:

    展开全文
  • 本篇主要参考《C++ Primer 第5版》,为什么派生类能向基类进行类型转换。 1. 派生类向基类的类型转换 C++ Primer P530 1.派生类对象中含有与其基类对应的组成部分,所以我们能把派生类的对象当成基类对象来使用,...
  • #include <iostream> using namespace std; class Base { public: virtual void show() { cout << "Base" << endl; } }; class Derived : public Base { public: void show() override { ....
  • C++派生类与继承(超详细)

    万次阅读 多人点赞 2020-05-13 22:59:09
    派生类的概念 1.为什么要使用继承 继承性也是程序设计中的一个非常有用的、有力的特性, 它可以让程序员在既有类的基础上,通过增加少量代码或修改少量代码的方法得到新的类, 从而较好地解决了代码重用的问题。 2.派生...
  • C++ 派生类的定义

    千次阅读 2021-01-07 00:41:28
    C++中,派生类的一般定义语法为: class 派生类名:继承方式 基类名1,继承方式 基类名2,....,继承方式 基类名n { 派生类成员声明; }; 派生类成员是指出了从基类继承来的所有成员之外,新增加的数据和函数成员...
  • C++派生类的继承方式 1.public:公有继承 采用公有公有继承方式创建的派生类对基类各种成员访问权限如下: (1)基类公有成员相当于派生类的公有成员, 即派生类可以象访问自身公有成员一样访问从基类继承的公有成员...
  • C++派生类中如何初始化基类对象

    千次阅读 2018-08-26 16:41:42
    C++派生类中如何初始化基类对象 今天收到盛大的面试,问我一个问题,关于派生类中如何初始化基类对象,我在想派生类对于构造函数不都是先构造基类对象,然后在构造子类对象,但是如果我们在成员初始化列表先初始化...
  • C++派生类构造函数的写法

    千次阅读 2020-04-06 09:46:42
    把点point类声明为shape的派生类,它包含两个数据成员x和y和输出函数display(); 把圆circle定义为点point类的派生类,它在点point的基础上增加一个数据成员radius; 并增加输出成员函数display ()和求面积成员函数...
  • C++派生类的构造函数

    千次阅读 多人点赞 2018-07-17 14:15:53
    构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。 在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的...
  • 构造依如下顺序: 1. 调用本的基类的构造函数 1.1 按照基类成员定义顺序对每个成员执行初始化 1.2 执行基类构造函数体 2. 调用本的构造函数 ...(C++Primer P531) 更进一步理解构造函数体的执行顺序:基...
  • c++派生类与继承实验报告
  • c++派生类及继承实验报告.doc
  • C++中,我们允许 将派生类对象赋给基类对象。(不允许将基类对象赋给派生类对象) ...原因很简单,派生类一般含有基类没有的成员,将派生类赋给基类成员我们才能保证基类中每个成员都能被赋值,用基类指...
  • c++派生类覆盖基类的问题

    千次阅读 2018-09-17 15:25:49
    派生类函数与基类函数同名,则会覆盖基类的函数调用,如下。 class Base{ private: int x; public : virtural void mf1()=0; virtural void mf1(int); virtual void mf2(); void mf3...
  • C++派生类对象定义时调用构造函数的顺序 当定义子类对象时,会调用父类和子类的构造函数,父类的函数体和列表初始先执行,子类的函数体和列表初始化后执行。
  • 基类对象与派生类对象的使用关系 派生类对象作为基类对象处理 由于派生类具有所有基类的成员所以把派生类的对赋给基类对象是合理的不过要求这种继承方式必须是public方式但是反过来赋值会使基类中一具有派生类的成员...
  • C++派生类让生活更简单
  • 1 简单的派生类的构造函数的一般形式 为:  派生类构造函数名(总参数表):基类构造函数名(参数表) {派生类中新增数据成员初始化语句} 2 有子对象的派生类的构造函数的一般形式为:  派生类构造函数名...
  • C++派生类的构造函数(构造函数的执行顺序)

    万次阅读 多人点赞 2018-06-16 16:01:55
    1、单继承时,派生类构造函数总是先调用基类构造函数再执行其他代码 1.1 派生类调用基类的构造函数  类的构造函数不能被继承,构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,...
  • #include using namespace std; class Line { public: void setLength( double len );... double getLength( void );...Line_Child::Line_Child(void):Line(10) //由于...派生类在创建对象时也会调用基类的构造函数

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 147,089
精华内容 58,835
关键字:

c++派生类