还剩43页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
继承与派生C++本课件将深入讲解C++中的继承与派生,涵盖基本概念、不同继承方式、虚函数和虚基类、构造和析构函数、静态成员、访问控制、类型转换以及继承的应用场景等内容中的继承C++代码复用代码扩展多态实现继承是一种面向对象编程的重要机制,它继承可以用来扩展现有类的功能,派生类继承是多态实现的基础,通过虚函数和抽允许我们创建新的类(派生类)并继承已可以添加新的属性和方法,从而实现对基象类,我们可以实现不同类型的对象执行有类的属性和方法(基类),从而实现代类功能的扩展同一方法的不同行为,提高代码的可扩展码复用,减少冗余代码性和灵活性继承的概念和特点继承是面向对象编程中的一种派生类可以访问基类的所有公机制,它允许一个类(派生类)共成员和受保护成员,但不能继承另一个类(基类)的属性直接访问基类的私有成员和方法继承关系是一种“is-a”关系,例如,汽车“is-a”交通工具基类与派生类基类派生类基类是被继承的类,也称为父类或超类它定义了派生类所继承派生类是继承自基类的类,也称为子类或派生类它可以继承基的属性和方法类的属性和方法,并添加新的属性和方法继承的形式公有继承(public)派生保护继承(protected)12类继承基类的所有公共成员和派生类继承基类的所有公共成受保护成员,并将其作为自己员和受保护成员,并将其作为的公共成员自己的受保护成员私有继承(private)派生类继承基类的所有公共成员和受保护成3员,并将其作为自己的私有成员公有继承代码示例继承特点在公有继承中,派生类可以访问基类的所有公共成员和受保护成class Animal{员,并将其作为自己的公共成员这意味着派生类的对象可以像public:使用基类对象一样使用继承的成员void move{cout动物正在移动endl;}};class Dog:public Animal{public:void bark{cout狗在叫endl;}};保护继承代码示例继承特点保护继承允许派生类访问基类的所有公共成员和受保护成员,但将其作为自己class Animal{的受保护成员这意味着派生类可以访问这些成员,但其子类只能通过派生类protected:来访问它们int age;public:void setAgeint a{age=a;}int getAge{return age;}};class Dog:protected Animal{public:void bark{cout狗在叫endl;}};私有继承代码示例继承特点私有继承将基类的所有公共成员和受保护成员都作为派生类的私有成员这意class Animal{味着派生类可以访问这些成员,但其子类和外部代码都不能直接访问private:int age;public:void setAgeinta{age=a;}int getAge{return age;}};class Dog:private Animal{public:void bark{cout狗在叫endl;}};多重继承代码示例继承特点多重继承允许一个派生类继承多个基类派生类可以继承所有基类的公共成员和受保class A{护成员,但需要明确指定继承方式,例如公有继承、保护继承或私有继承public:void methodA{coutA类的方法endl;}};class B{public:void methodB{coutB类的方法endl;}};class C:public A,public B{public:void methodC{coutC类的方法endl;}};虚函数和虚基类虚函数是指在基类中声明为virtual的函数,它允许在派生类中重写基类1中的函数,从而实现多态性虚基类是指在继承关系中被多个派生类共享的基类,它确保派生类的对象2只包含基类的一个副本,而不是多个副本虚函数的实现代码示例实现机制虚函数的实现利用虚函数表(vtable)来实现每个类都有一个虚函数表,其中存储class Animal{了该类的所有虚函数的地址派生类重写虚函数后,会更新自己的虚函数表,指向新public:实现的函数地址virtual void makeSound{cout动物在叫endl;}};class Dog:public Animal{public:void makeSoundoverride{cout狗在叫endl;}};class Cat:public Animal{public:void makeSoundoverride{cout猫在叫endl;}};虚函数与多态代码示例多态实现通过虚函数,我们可以使用基类指针指向不同类型的派生类对象,Animal*animal=new Dog;并调用相同的方法,但执行不同的行为这就是多态性的体现,animal-makeSound;//输出:狗在叫它允许我们用统一的方式处理不同类型的对象animal=new Cat;animal-makeSound;//输出:猫在叫纯虚函数与抽象类代码示例概念解释纯虚函数是虚函数,但没有函数体抽象类是指包含至少一个纯class Shape{虚函数的类抽象类不能直接实例化,只能作为基类被继承,用public:于定义接口,强制派生类实现纯虚函数virtual double getArea=0;//纯虚函数};class Circle:public Shape{public:doublegetAreaoverride{return
3.14159*radius*radius;}private:double radius;};抽象类的使用代码示例应用场景抽象类主要用于定义接口,强制派生类实现特定的方法,例如在Shape*shape=new Circle5;//创建一个圆形对象图形系统中,使用Shape类来定义图形的接口,不同的图形类coutshape-getAreaendl;//输出:(圆形、矩形等)需要实现getArea方法来计算面积
78.5397构造函数与析构函数构造函数析构函数构造函数是在创建对象时自动调用的函数,用于初始化对象的成析构函数是在对象销毁时自动调用的函数,用于释放对象占用的员变量它与类同名,没有返回值类型资源它以“~”开头,后面跟类名,没有返回值类型构造函数的继承代码示例继承特点派生类的构造函数必须先调用基类的构造函数来初始化基类成员,可以使用class Animal{初始化列表来实现初始化列表中的基类构造函数调用必须放在派生类构造public:函数参数列表之后Animalstring name:namename{coutAnimal构造函数endl;}private:string name;};class Dog:public Animal{public:Dogstring name,int age:Animalname,ageage{coutDog构造函数endl;}private:int age;};析构函数的继承代码示例继承特点派生类的析构函数会在对象销毁时自动调用,它会先调用基类的析构函数来释放基类成员占用class Animal{的资源,然后释放派生类成员占用的资源public:Animalstring name:namename{coutAnimal构造函数endl;}~Animal{coutAnimal析构函数endl;}private:string name;};class Dog:public Animal{public:Dogstring name,int age:Animalname,ageage{coutDog构造函数endl;}~Dog{coutDog析构函数endl;}private:int age;};虚析构函数代码示例应用场景当使用基类指针指向派生类对象时,如果基类的析构函数不是虚class Animal{函数,那么在释放基类指针时,只有基类的析构函数会被调用,public:派生类的析构函数不会被调用,导致内存泄漏为了避免这种情virtual~Animal{况,需要将基类的析构函数声明为虚函数coutAnimal析构函数endl;}};class Dog:public Animal{public:~Dog{coutDog析构函数endl;}};利用初始化列表代码示例使用建议在派生类的构造函数中,使用初始化列表来初始化成员变量是一class Animal{种良好的编程习惯,因为它可以提高代码的可读性和效率例如,public:在上面的代码中,我们使用初始化列表来初始化基类Animal中Animalstring name:namename{}的name成员变量和派生类Dog中的age成员变量private:string name;};class Dog:public Animal{public:Dogstring name,int age:Animalname,ageage{}private:int age;};继承中的静态成员代码示例继承特点静态成员属于类,而不是对象,每个类只有一个静态成员的副本class Animal{派生类可以继承基类的静态成员,但不能修改基类的静态成员public:在派生类中,可以使用基类名和作用域运算符来访问基类的静态static int count;成员};int Animal::count=0;//静态成员初始化class Dog:public Animal{public:void bark{cout狗在叫endl;}};继承中的静态成员函数代码示例继承特点静态成员函数属于类,而不是对象,它可以通过类名和作用域运算符来调class Animal{用派生类可以继承基类的静态成员函数,并可以直接调用它们public:static voidprintCount{cout动物数量:countendl;}private:static intcount;};int Animal::count=0;class Dog:public Animal{public:void bark{cout狗在叫endl;}};访问控制与继承代码示例访问控制在继承中,派生类对基类成员的访问权限取决于基类成员的访问控制和class A{继承方式例如,在公有继承中,派生类可以访问基类的公共成员和受private:保护成员,但不能访问基类的私有成员inta;protected:int b;public:intc;};class B:public A{public:void printB{coutbendl;//可以访问保护成员b}};保护成员的特点保护成员是基类中声明为protected的成员变量和方法它们只能被1基类本身和其派生类访问保护成员通常用于定义基类内部需要被派生类访问但不想被外部代码2访问的成员保护成员的继承代码示例继承特点在保护继承中,派生类将继承基类的保护成员,并将其作为自己class Animal{的保护成员这意味着派生类可以访问这些成员,但其子类只能protected:通过派生类来访问它们string name;public:Animalstring name:namename{}};class Dog:public Animal{public:void printName{coutnameendl;//可以访问保护成员name}};类型转换与继承动态类型转换在运行时根据对象的实际类型进行类型转换,使用1dynamic_cast运算符静态类型转换在编译时根据变量的声明类型进行类型转换,使用2static_cast运算符动态类型转换代码示例应用场景动态类型转换主要用于在运行时根据对象的实际类型执行不同的操作例如,在图形系统class Animal{中,使用dynamic_cast来判断一个图形对象是否是圆形,如果是,则调用其计算面积的public:方法virtual voidmakeSound{cout动物在叫endl;}};class Dog:public Animal{public:voidmakeSoundoverride{cout狗在叫endl;}};Animal*animal=new Dog;Dog*dog=dynamic_castanimal;if dog!=nullptr{dog-bark;//只有当animal指向Dog对象时,才能调用bark方法}else{coutanimal不是Dog类型的对象endl;}静态类型转换代码示例应用场景静态类型转换主要用于在编译时进行类型转换,它是一种安全的类型转换,class Animal{不会导致运行时错误例如,将派生类对象转换为基类对象时,可以使用public:static_cast运算符Animalstring name:namename{}private:string name;};class Dog:public Animal{public:Dogstring name,int age:Animalname,ageage{}private:int age;};Dog*dog=new Dog旺财,3;Animal*animal=static_castdog;//将Dog对象转换为Animal对象常量对象与继承代码示例继承特点常量对象不能修改其成员变量的值常量成员函数是指声明为class Animal{const的成员函数,它不能修改对象的状态常量对象只能调用public:常量成员函数,以确保其状态不会被改变Animalstring name:namename{}void printNameconst{coutnameendl;}private:string name;};const Animal animal小猫;//创建一个常量Animal对象animal.printName;//可以调用常量成员函数常量成员函数代码示例使用建议如果一个成员函数不修改对象的状态,那么应该将其声明为class Animal{const成员函数,这样可以提高代码的可读性和安全性例如,public:在上面的代码中,printName函数只输出对象的name成员Animalstring name:namename{}变量的值,它不修改对象的状态,因此应该将其声明为const成void printNameconst{员函数coutnameendl;}private:string name;};常量对象的初始化代码示例初始化方法常量对象必须在声明时进行初始化,并且初始化值必须是常量表class Animal{达式,例如字面量或常量变量常量对象不能在构造函数中进行public:初始化Animalstring name:namename{}private:string name;};const Animalanimal小猫;//创建一个常量Animal对象常量引用代码示例应用场景常量引用可以用来引用常量对象,它可以保证引用的对象不会被const Animalanimal小猫;修改常量引用可以提高代码的效率和安全性const Animalref=animal;//创建一个常量引用友元与继承代码示例继承特点友元关系不具有传递性,也就是说,如果A类是B类的友元,而class Animal{B类是C类的友元,那么A类并不一定是C类的友元友元关系是private:用来打破类的封装性,在某些情况下可以提高代码的效率或灵活string name;性friend class Dog;//声明Dog类为Animal类的友元类};class Dog{public:void printNameAnimalanimal{coutanimal.nameendl;//可以访问Animal类的私有成员name}};友元函数的调用代码示例调用方式友元函数可以通过友元关系访问类的私有成员和保护成员友元Animalanimal小猫;函数可以通过对象名和作用域运算符来调用,也可以通过友元类Dog dog;的对象来调用dog.printNameanimal;//通过Dog类的友元函数访问Animal类的私有成员友元类的定义代码示例定义方法友元类可以通过在友元类的声明中使用friend关键字来定义友class Animal{元类可以访问友元类的所有成员,包括私有成员和保护成员private:string name;friend class Dog;//声明Dog类为Animal类的友元类};class Dog{public:void printNameAnimalanimal{coutanimal.nameendl;//可以访问Animal类的私有成员name}};继承与公有成员访问代码示例访问特点在公有继承中,派生类可以访问基类的所有公有成员和受保护成员,并将其作为自己的公有成class Animal{员这意味着派生类可以像使用基类对象一样使用继承的成员public:Animalstring name:namename{}void printName{coutnameendl;}private:string name;};class Dog:public Animal{public:Dogstring name,int age:Animalname,ageage{}void bark{cout狗在叫endl;}private:int age;};Dog dog旺财,3;dog.printName;//可以访问基类的公有成员printName继承与保护成员访问代码示例访问特点在公有继承中,派生类可以访问基类的所有公有成员和受保护成员这意味着派生类class Animal{可以像使用基类对象一样使用继承的成员protected:string name;public:Animalstring name:namename{}};classDog:public Animal{public:Dogstring name,int age:Animalname,ageage{}void printName{coutnameendl;//可以访问基类的保护成员name}private:int age;};Dog dog旺财,3;dog.printName;//可以访问基类的保护成员name继承与私有成员访问代码示例访问特点在所有继承方式中,派生类都不能直接访问基类的私有成员这是因为私有class Animal{成员是基类内部的私有数据,它们只能被基类本身访问,不能被任何其他类private:访问,包括派生类string name;public:Animalstring name:namename{}};classDog:public Animal{public:Dogstring name,int age:Animalname,ageage{}private:int age;};Dog dog旺财,3;//dog.name=小黑;//错误:不能访问基类的私有成员name继承的应用场景图形系统银行账户管理系统使用基类Shape来定义图形的使用基类Account来定义银行接口,不同的图形类(圆形、矩账户的公共属性和方法,不同的形等)继承Shape类并实现账户类型(储蓄账户、信用卡账getArea方法来计算面积户等)继承Account类并添加自己的特殊属性和方法学生管理系统使用基类Student来定义学生的基本信息,不同的学生类型(本科生、研究生等)继承Student类并添加自己的特殊信息和方法继承的设计原则“is-a”关系只有当派生类是基类的特例时,才使用继承代码复用使用继承来实现代码复用,减少重复代码可扩展性使用继承来扩展现有类的功能,提高代码的可扩展性多态性使用继承和虚函数来实现多态性,提高代码的灵活性和可维护性案例分析基于继承的银行账户管理系统类结构派生类派生类基类Account定义银行账户的基本属储蓄账户类SavingAccount继承自信用卡账户类CreditCardAccount性和方法,例如账户号、账户余额、存款、Account类,添加利率属性和计算利息继承自Account类,添加信用额度属性取款等方法和计算账单方法案例分析基于继承的图形系统类结构派生类派生类基类Shape定义图形的接口,包含计圆形类Circle继承自Shape类,添加矩形类Rectangle继承自Shape类,算面积、周长等方法半径属性和实现计算圆形面积和周长的方添加长宽属性和实现计算矩形面积和周长法的方法案例分析基于继承的学生管理系统类结构派生类派生类基类Student定义学生的基本信息,本科生类Undergraduate继承自研究生类Graduate继承自Student例如学号、姓名、性别等Student类,添加专业、年级等信息类,添加导师、研究方向等信息课程总结继承是一种重要的面向对象编程机制,不同的继承方式(公有、保护、私有)虚函数和抽象类可以实现多态性,允它可以实现代码复用、扩展和多态性决定了派生类对基类成员的访问权限许用统一的方式处理不同类型的对象继承与构造函数、析构函数、静态成员、访问控制、类型转继承在图形系统、银行账户管理系统、学生管理系统等各种换等机制密切相关应用场景中都有广泛应用学习建议深入理解继承的概念、特点和不同继承方式掌握虚函数、抽象类的实现和应用练习编写使用继承的程序,并分析不同继承方式的代码学习继承在实际应用场景中的使用案例,例如图形系统、银行账户管理系统等参考资料《C++Primer Plus》《C++程序设计语言》《Effective C++》。
个人认证
优秀文档
获得点赞 0