【C++】从零开始认识继承

2024-05-13 1766阅读

【C++】从零开始认识继承

送给大家一句话:

其实我们每个人的生活都是一个世界,即使最平凡的人也要为他生活的那个世界而奋斗。 – 路遥 《平凡的世界》

✩◝(◍⌣̎◍)◜✩✩◝(◍⌣̎◍)◜✩✩◝(◍⌣̎◍)◜✩

✩◝(◍⌣̎◍)◜✩✩◝(◍⌣̎◍)◜✩✩◝(◍⌣̎◍)◜✩

✩◝(◍⌣̎◍)◜✩✩◝(◍⌣̎◍)◜✩✩◝(◍⌣̎◍)◜✩


从零开始认识继承

  • 1 前言
  • 2 什么是继承
  • 3 开始使用继承
    • 3.1 继承的语法格式
    • 3.2 基类与派生类的赋值转换
    • 3.3 继承中的作用域
    • 3.4 派生类的默认成员函数
      • 构造函数
      • 拷贝构造函数
      • 赋值构造函数
      • 析构函数
      • 总结
      • 4 继承与友元
      • 5 继承与静态变量
      • 6 复杂的菱形继承及菱形虚拟继承
      • 7 继承的总结和思考
      • 8 有关继承的经典面试题
      • Thanks♪(・ω・)ノ谢谢阅读!!!
      • 下一篇文章见!!!

        1 前言

        在我们日常的编程中,继承的应用场景有很多。它可以帮助我们节省大量的时间和精力,避免重复造轮子的尴尬。同时,它也让我们的代码更加模块化,易于维护和扩展。可以说,继承技术是C++的灵魂。

        那么,继承技术的起源又是什么呢?这得追溯到遥远的过去,当时的程序员们发现,许多类的属性和方法都是相似的,于是他们想出了一个绝妙的主意:为什么不把这些相似的部分提取出来,形成一个"父类",而其他的类则通过"继承"这个父类来获得这些属性和方法呢?这个想法,就是继承技术的雏形。

        如今,继承技术已经成为C++编程中不可或缺的一部分。它让我们能够站在巨人的肩膀上,创造出更加高效、简洁的代码。当然,继承技术也不是万能的,它也有自己的局限性和注意事项。但是,这并不妨碍我们欣赏它的优雅,感受它带来的便利。

        在这篇博客中,我将带你深入探讨C++继承技术的奥秘,让你能够更好地掌握这一强大的工具。准备好了吗?让我们一起踏上这场探索之旅,开启编程的新篇章 — C++进阶!!!

        2 什么是继承

        继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。

        通过继承联系在一起的类构成一种层次关系,通常在层次关系的根部有一个基类(base class),其他类则是直接或间接地从基类继承过来的,这些继承来的类成为派生类(derived class)。基类负责定义在层次关系中所有类共同拥有的成员,而每个派生类都有各自特定的成员。

        举个例子:加入我们需要一个学校管理系统,那么成员包括学生,老师,保安,宿管…不管是什么身份,总得是个人吧,是人就会有名字,年龄,家庭住址等基础信息,那么我们就可以把这些共同的部分提炼出来作为基类。

        #include
        using namespace std;
        //共同特性
        class Person
        {
        public:
        	void Print()
        	{
        		cout 
        protected:
        	int _stuid; // 学号
        };
        class Teacher : public Person
        {
        protected:
        	int _jobid; // 工号
        };
        int main()
        {
        	Student s;
        	Teacher t;
        	s.Print();
        	t.Print();
        	return 0;
        }
        
        public:
        	Person(int age = 18, int sex = 1, int num = 0)
        		:_age(age),
        		_sex(sex),
        		_num(num)
        	{}
        	void Print()
        	{
        		cout
        public:
        	Student(int num = 0)
        		:_num(num)
        	{
        	}
        	void Print()
        	{
        		cout 
        	Student s(1111);
        	s.Print();
        	return 0;
        }
        
        public:
        	//因为不是全缺省函数没有默认构造
        	Person(const char* name )
        		: _name(name)
        	{
        		cout 
        public:
        protected:
        	int _num; //学号
        };
        void Test()
        {
        	Student s1;
        }
        int main()
        {
        	Test();
        	return 0;
        }
        
        public:
        	Student(int num , const char* str ,const char* name)
        		:_name(name),
        		_num(num),
        		_str(str)
        	{
        	}
        protected:
        	int _num; //学号
        	string _str;
        };
        
        public:
        	Student(int num , const char* str ,const char* name)
        		:Person(name),
        		_num(num),
        		_str(str)
        	{
        	}
        protected:
        	int _num; //学号
        	string _str;
        };
        
        public:
        	BB(int num , const char* str ,const char* name)
        		:_p(name),
        		_num(num),
        		_str(str)
        	{}
        protected:
        	Person _p
        	int _num; //学号
        	string _str;
        };
        
        public:
        	Student(int num , const char* str ,const char* name)
        		:Person(name),
        		_num(num),
        		_str(str)
        	{}
        	Student(const Student& s)
        		:Person(s)//会进行切片,子类对象可以赋值给父类  -复用
        		,_num(s._num)
        		,_str(s._str)
        	{}
        protected:
        	int _num; //学号
        	string _str;
        };
        
        public:
        	Student(int num , const char* str ,const char* name)
        		:Person(name),
        		_num(num),
        		_str(str)
        	{}
        	Student& operator=(const Student& s)
        	{
        		//不能自己赋值自己
        		if(this != &s)
        		{
        			//注意标明作用域 , 否则会无限递归
        			Person::operator=(s); //进行切片来对父类进行赋值拷贝 -复用
        			_num = s._num;
        			_str = s._str;//调用string的构造
        		}
        	}
        protected:
        	int _num; //学号
        	string _str;
        };
        
        public:
        	Student(int num , const char* str ,const char* name)
        		:Person(name),
        		_num(num),
        		_str(str)
        	{}
        	~Student(int num , const char* str ,const char* name)
        	{
        		~Person();
        		cout
        public:
        	Dad(int money = 100  , const char* house = "homeless")
        		:_money(money)
        		,_house(house)
        	{}
        	friend void show(const Dad& d, const Son& s);
        protected:
        	int _money;
        	string _house;
        };
        class Son : public Dad
        {
        public:
        	Son(int homework = 100  )
        		:_homework(homework)
        	{}
        	//friend void show(const Dad& d, const Son& s);
        protected:
        	int _homework;;
        };
        void show(const Dad& d , const Son& s)
        {
        	cout 
        	Dad d(10000, "翻斗花园");
        	Son s(12);
        	show(d,s);
        	return 0;
        }
        
        public:
        	static int _a ;
        };
        int A::_a = 1;
        class B : public A
        {
        public:
        protected:
        	int b;
        };
        int main()
        {
        	B b1;
        	B b2;
        	B b3;
        	cout 
        public:
        	Person() { ++_count; }
        protected:
        	string _name; // 姓名
        public:
        	static int _count; // 统计人的个数。
        };
        int Person::_count = 0;
        class Student : public Person
        {
        protected:
        	int _stuNum; // 学号
        };
        void TestPerson()
        {
        	Student s1;
        	Student s2;
        	Student s3;
        	cout 
        	TestPerson();
        	return 0;
        }
        
        public:
        	string _name; // 大学名字
        };
        class uni211 : public university
        {
        protected:
        	int _num; //编号
        };
        class uni985 : public university
        {
        protected:
        	int _id; // 编号
        };
        class  SDU : public uni211, public uni985
        {
        protected:
        	string _address;
        };
        void Test()
        {
        	// 这样会有二义性无法明确知道访问的是哪一个
        	SDU a;
        	a._name = "peter";
        	// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
        	a.uni211::_name = "xxx";
        	a.uni985::_name = "yyy";
        }
        
        public:
        	string _name; // 大学名称
        };
        class uni211 : virtual public university
        {
        protected:
        	int _num; //编号
        };
        class uni985 : virtual public university
        {
        protected:
        	int _id; //编号
        };
        class  SDU : public uni211, public uni985
        {
        protected:
        	string _address;//地址
        };
        void Test()
        {
        	// 这样就只有一个_name了,不存在二义性的问题了
        	SDU 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;
        }
        
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]