C++必修:深入理解继承与虚继承
✨✨ 欢迎大家来到贝蒂大讲堂✨✨
🎈🎈养成好习惯,先赞后看哦~🎈🎈
所属专栏:C++学习
贝蒂的主页:Betty’s blog
1. 继承的概念与定义
1.1. 继承的概念
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,而继承是类设计层次的复用。
比如说一个人,他具有身高,年龄,姓名等个人信息,然后利用这些信息我们可以定义一个Person类。而当我们想定义一个学生Student类时,学生首先肯定是一个人,所以这时候我们可以复用Person类。但是学生除了具备一个人的基本信息外,还具有学号,专业等特有信息,这时候我们就需要在Student类中继续添加。
1.2. 继承的定义
继承的用法十分简单,如下:
class derived - class : access - specifier base - class
- derived-class:被称为父类,也叫作基类。
- access-specifier:是继承方式限定符,分为public,protected,private继承。
- **base-class:**被称为子类,也叫作派生类。
下面是一个Student类继承Person类的具体实例:
Pythonclass Person { public: void Print() { cout private: int _stuid = 123456;//学号 int _grade = 10;//年级 }; private: void Print() { cout public: void Print()//类里不可访问 { cout Student s; s.Print();//类外不可访问 return 0; } protected: double _height = 1.73;//身高 int _age = 18 ;//年龄 string _name ="betty";//姓名 }; class Student :public Person { public: void Print()//隐藏 { cout Student s; s.Print(); return 0; } cout public: void fun() { cout public: void fun(int i) { A::fun(); cout B b; b.fun(10); }; public: Person(const char* name = "peter") : _name(name) { cout cout public: Student() { cout cout Student s; return 0; } public: Person(const char* name)//没有默认构造 : _name(name) { } Person(const Person& p) : _name(p._name) { } protected: string _name; // 姓名 }; class Student : public Person { public: Student(int num, const char* name) :_num(num) //,_name(name) error , Person(name)//正确初始化 { ; } protected: int _num; //学号 }; cout cout cout //因为构成覆盖关系,所以指定域作用限定符 Person::~Person(); cout } //赋值重载 Person& operator=(const Person& p) { if (this != &p) _name = p._name; return *this; } Student(const Student& s)//拷贝构造 :_num(s._num) , Person(s)//派生类赋值给基类 { ; } //赋值重载 Student& operator = (const Student& s) { if (this != &s) { //加域作用限定,否则发生死循环 Person::operator =(s); _num = s._num; } return *this; } public: friend void Display(const Person& p, const Student& s); protected: string _name; // 姓名 }; class Student : public Person { protected: int _stuNum; // 学号 }; void Display(const Person& p, const Student& s) { cout Person p; Student s; Display(p, s); return 0; } public: Person() { ++_count; } string _name; // 姓名 static int _count; // 统计人的个数。 }; int Person::_count = 0;//静态成员初始化 class Student : public Person { protected: int _stuNum; // 学号 }; class Graduate : public Student { protected: string _seminarCourse; // 研究科目 }; int main() { Person p; Student s; Graduate g; cout public: string _name; // 姓名 }; class Student : public Person { protected: int _num; //学号 }; class Teacher : public Person { protected: int _id; // 职工编号 }; class Assistant : public Student, public Teacher { protected: string _majorCourse; // 主修课程 }; void Test() { Assistant a; // a._name = "peter"; 这样会产生二义性无法明确知道访问的是哪一个类 // 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决 a.Student::_name = "xxx"; a.Teacher::_name = "yyy"; } public: string _name; // 姓名 }; //虚继承 class Student : virtual public Person { protected: int _num; //学号 }; //虚继承 class Teacher : virtual public Person { protected: int _id; // 职工编号 }; class Assistant : public Student, public Teacher { protected: string _majorCourse; // 主修课程 }; void Test() { Assistant a; a._name = "peter"; } public: int _a; }; // class B : public A class B : virtual public A { public: int _b; }; // class C : public A class C : virtual public A { public: int _c; }; class D : public B, public C { public: int _d; }; int main() { D d; d.B::_a = 1; d.C::_a = 2; d._b = 3; d._c = 4; d._d = 5; return 0; } }; class B : public A {}; }; class B { A _aa; };
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!