继承和多态
2021/7/16 23:13:55
本文主要是介绍继承和多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
继承:
类与类之间的关系
组合类:
一个类是另一个类的一部分
例:head --- {eye,nose}
代理类:
一个类中的方法是另一个类方法的子集
例:list --- > stack
继承:
一个类是另一个类的一种
例:动物 ----> 猫 狗..
三种访问属性:
1:可访问 0:不可访问
外界 子类 自身
public: 1 1 1
protected: 0 1 1
private: 0 0 1
继承的写法:
在子类的类定义后面加上 : 父类名字
继承权限:
public:
protect:
private:
默认继承权限是private
class A { public: int a; void fun1() { cout << "public void fun1() " << endl; } protected: int b; void fun2() { cout << "protected void fun2() " << endl; } private: int c; void fun3() { cout << "private void fun3() " << endl; } };
继承权限限制的是子类继承父类之后,父类的成员在子类中的最低访问权限
如果采用private的方式继承,则会将父类中的public和protected放在子类中的private
子类中可以访问,外界不可访问
采用public继承时,private继承不下来
class B :public A { public: int a; void fun1() { cout << "public void fun1() " << endl; } int a1; protected: int b; void fun2() { cout << "protected void fun2() " << endl; } void fun_tmp() { cout << a << endl;//A::public cout << b << endl;//A::protected //cout << c << endl;//A::private } int b1; private: /* */ int c1; };
采用protected继承时,只能继承protected
class B :protected A { public: int a1; protected: int b; void fun2() { cout << "protected void fun2() " << endl; } void fun_tmp() { cout << a << endl;//A::public cout << b << endl;//A::protected //cout << c << endl;//A::private } int b1; private: /* */ int c1; };
采用private时,一个都继承不了(相当于私有继承)
class B :private A { public: int a1; protected: int b1; private: /* */ int c1; };
继承方式一般采用public
函数之间的关系
重载
继承中成员方法的关系
隐藏
子类中的成员方法会隐藏父类中同名的成员方法 ------ 同名隐藏
访问被隐藏的父类成员方法使用父类作用域即可
覆盖
类的构造顺序:
组合类:
class A{}
class B
{
B():A(){}
A a;
}
B b;
先构造成员对象 ---》 再构造自身对象
先析构自身对象----》再析构成员对象
继承类:
先构造父类 ---- 》再构造子类 ------子类的构造函数一定在初始化列表进行了父类的构造
先析构子类 -----》再析构父类
如果类中存在必须再自身构造之前需要完成的事情,就一定要在初始化列表中完成
#include<string> class Animal { public: Animal(const string& name) :_name(name)//初始化列表 { cout << "Animal(const string& name)" << endl; } void eat() { cout << _name << " eat eat eat……" << endl; } void run() { cout << _name << " walk walk walk……" << endl; } ~Animal() { cout << "~Animal()" << endl; } protected: const string _name; }; class Cat : public Animal { public: Cat(const string& name) :Animal(name) { cout << "Cat(const string& name)" << endl; } void sleep() { cout << _name << " sleep sleep sleep ……" << endl; } void eat(int a)//同名隐藏 { cout << _name << " eat fish……" << endl; } ~Cat() { cout << "~Cat()" << endl; } /* void eat() { cout << _name << " eat eat eat……" << endl; } void run() { cout << _name << " walk walk walk……" << endl; } */ }; int main() { Cat cat("cat"); //cat.eat(); //cat.Animal::eat(); //Animal a("ss"); return 0; }
覆盖
虚函数:
virtual修饰的成员方法就是虚函数
.text
.data .bss
.rodata---只读数据段 read only data 虚函数表存放在rodata段
虚函数的调用
对象调用
直接取text段调用对应的函数指令
对象指针调用
会先去虚函数表中找到对应的虚函数指针
再去text段中虚函数指针对应的位置调用找到的函数
virtual存在继承性
比如父类中为 virtual void fun1() 子类中为 void fun1()
则子类中的fun1同样会被处理为virtual
虚函数在继承中存在覆盖的可能性
覆盖的条件:
1.父类中的成员方法必须是虚函数
2.子类中成员方法和父类中成员方法相同---(函数名相同,参数列表相同,返回值相同)
如果多个父类中存在虚表,继承之后子类中就会有多个虚表
class Base2 { public: int b; virtual void fun5() { cout << "Base2::fun5()" << endl; } virtual void fun6() { cout << "Base2::fun6()" << endl; } virtual void fun() { cout << "Base2::fun()" << endl; } }; class Base { public: int a; virtual void fun1() { cout << "Base::fun1()" << endl; } virtual void fun2() { cout << "Base::fun2()" << endl; } void fun3() { cout << "Base::fun3()" << endl; } virtual void fun() { cout << "Base::fun()" << endl; } }; class Drive : public Base2, public Base { public: void fun1() { cout << "Drive::fun1()" << endl; } void fun5() { cout << "Drive::fun5()" << endl; } virtual void fun4() { cout << "Drive::fun4()" << endl; } void fun() { cout << "Drive::fun()" << endl; } int c; }; typedef void(*TYPE_FUN)(); void printf_vftable(TYPE_FUN* table) { for (int i = 0; table[i] != NULL; i++) { cout << "[" << i << "]" << table[i] << endl; table[i](); } } int main() { #if 0 cout << sizeof(Base) << endl; Base tmp1; /* Drive tmp2; tmp2.fun1(); tmp2.Base::fun1(); */ //父类指针指向子类对象 Drive* p = new Drive(); p->fun1(); p->Base::fun1(); Drive tmp2; #endif //Base tmp1; //Base* tmp = &tmp1; //printf_vftable(((TYPE_FUN**)tmp)[0]); Drive tmp2; Base* tmpp = &tmp2; //printf_vftable(((TYPE_FUN**)tmpp)[0]); tmpp->fun(); return 0; }
函数之间的关系重载
继承中成员方法的关系隐藏子类中的成员方法会隐藏父类中同名的成员方法 ------ 同名隐藏访问被隐藏的父类成员方法使用父类作用域即可
覆盖
这篇关于继承和多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-11有哪些好用的家政团队管理工具?
- 2025-01-11营销人必看的GTM五个指标
- 2025-01-11办公软件在直播电商前期筹划中的应用与推荐
- 2025-01-11提升组织效率:上级管理者如何优化跨部门任务分配
- 2025-01-11酒店精细化运营背后的协同工具支持
- 2025-01-11跨境电商选品全攻略:工具使用、市场数据与选品策略
- 2025-01-11数据驱动酒店管理:在线工具的核心价值解析
- 2025-01-11cursor试用出现:Too many free trial accounts used on this machine 的解决方法
- 2025-01-11百万架构师第十四课:源码分析:Spring 源码分析:深入分析IOC那些鲜为人知的细节|JavaGuide
- 2025-01-11不得不了解的高效AI办公工具API