当前位置: 首页 > news >正文

南昌行业网站建设jsp网站 iis

南昌行业网站建设,jsp网站 iis,个人网站转企业,网站建设 天猫 保证金文章目录 多态概念及其触发条件重写和协变#xff08;考点1#xff09;#xff08;考点2#xff09; 虚函数表及其位置#xff08;考点3#xff09; 多继承中的虚函数表 多态概念及其触发条件 多态的概念#xff1a;通俗来说#xff0c;就是多种形态。具体点就是去完成… 文章目录 多态概念及其触发条件重写和协变考点1考点2 虚函数表及其位置考点3 多继承中的虚函数表 多态概念及其触发条件 多态的概念通俗来说就是多种形态。具体点就是去完成某个行为当不同的对象去完成时会产生出不同的状态 多态的构成条件 1.必须通过基类的指针或者引用调用虚函数即被virtual修饰的类成员函数称为虚函数2.被调用的函数必须是虚函数且派生类必须对基类的虚函数进行重写 重写和协变 虚函数的重写(覆盖)派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数类型)称子类的虚函数重写了基类的虚函数 虚函数重写的两个例外 1. 协变(基类与派生类虚函数返回值类型不同)   派生类重写基类虚函数时与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引用派生类虚函数返回派生类对象的指针或者引用时称为协变 2. 析构函数的重写(基类与派生类析构函数的名字不同)   如果基类的析构函数为虚函数此时派生类析构函数只要定义无论是否加virtual关键字都与基类的析构函数构成重写虽然基类与派生类析构函数名字不同。虽然函数名不相同看起来违背了重写的规则其实不然这里可以理解为编译器对析构函数的名称做了特殊处理编译后析构函数的名称统一处理成destructor override和final两个关键字 考点1 这里强调一下重写重写的是实现。看以下这个场景考点 class A { public:A(){}virtual void func(int val 1) {std::cout A- val std::endl; }virtual void test() {func(); } }; class B : public A { public:void func(int val 0) { std::cout B- val std::endl; } }; int main() {A* p new B();p-test();return 0; }打印结果为B-1说明调的是子类的func函数但是缺省值用的却是父类返回值函数名参数类型相同即构成重写重写重写的是实现壳子用的是父类的写的内容自己控制 考点2 那为什么要把析构函数构成重写呢看以下这个场景考点 class Person { public:~Person() { cout ~Person() endl; } }; class Student : public Person { public:~Student() {cout ~Student() endl;delete[] ptr;} protected:int* ptr new int[10]; };int main() {Person* p new Person;delete p;p new Student;delete p; return 0; }当我们用父类指针指向子类对象时期望析构的是子类对象而不是父类对象。不构成重写的话无论父类指针是指向子类对象还是父类对象析构的都是父类对象导致下面的 ptr 动态开辟的空间没有释放而内存泄漏   当我们给父类析构函数加上 virtual让其构成重写后。同时注意这里析构玩~Student后还会析构继承父类照应上面的构造先父后子析构先子后父 抽象类   在虚函数的后面写上 0 则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类也叫接口类抽象类不能实例化出对象。派生类继承后也不能实例化出对象只有重写纯虚函数派生类才能实例化出对象。纯虚函数规范了派生类必须重写另外纯虚函数更体现出了接口继承 动态绑定与静态绑定 虚函数表及其位置 一个含有虚函数的类中都至少都有一个虚函数表指针因为虚函数的地址要被放到虚函数表中虚函数表也简称虚表通过下面这个例子来看对象模型 考点3 这时候我们再反过来思考为什么一定是父类的指针或者引用而不能是父类对象 首先我们可以看出子类对象会先拷贝父类虚函数表然后再对需要重写的虚函数进行地址修改。   假如我们把子类对象赋值给父类对象那么子类对象的虚函数表要不要拷贝给父类如果虚函数表不拷贝那么还是调用父类的函数没有构成多态。   如果拷贝了那么父类对象的虚函数表存的是子类对象修改后的虚函数如下图此时我们无法再调用父类本身被重写的函数因为无论我们传子类还是父类对象调用的都是子类对象的函数不能构成多态。   因此多态的条件一定是父类的指针或者引用这样可以避免像下面这样拷贝带来的错误。 虚表位置 class Person { public:virtual void BuyTicket() const { cout 成人-全价 endl; } }; class Student : public Person { public:virtual void BuyTicket() const { cout 学生-半价 endl; } }; int main() {Person ps;Student st;int a 0;printf(栈%p\n\n, a);static int b 0;printf(静态区%p\n\n, b);int* p new int;printf(堆%p\n\n, p);const char* str hello world;printf(常量区%p\n\n, str);printf(虚表1%p\n, *((int*)ps));printf(虚表2%p\n, *((int*)st));return 0; }虚表存放在哪里呢首先排除堆虚表由编译器生成不会自己去动态申请空间。其次排除栈同类型对象公用一张虚表栈都是伴随栈帧走的不能函数调用结束栈帧销毁虚表就销毁了吧。我们用打印的方式来看一下虚表是存在哪里的   看下面的代码和输出结果我们可以发现虚表是存在常量区的 多继承中的虚函数表 // 打印函数指针数组 typedef void(*FUNC_PTR) (); void PrintVFT(FUNC_PTR* table) {for (size_t i 0; table[i] ! nullptr; i){printf([%d]:%p-, i, table[i]);FUNC_PTR f table[i];f();//这个地址可以调用说明一定是函数}printf(\n); }class Base1 { public:virtual void func1() { cout Base1::func1 endl; }virtual void func2() { cout Base1::func2 endl; } private:int b1; }; class Base2 { public:virtual void func1() { cout Base2::func1 endl; }virtual void func2() { cout Base2::func2 endl; } private:int b2; };class Derive : public Base1, public Base2 { public:virtual void func1() { cout Derive::func1 endl; }virtual void func3() { cout Derive::func3 endl; } private:int d1; };int main() {Derive d;int vft1 *((int*)d);Base2* ptr d;int vft2 *((int*)ptr);printf(第一张虚表\n);PrintVFT((FUNC_PTR*)vft1);printf(第二张虚表\n);PrintVFT((FUNC_PTR*)vft2);return 0; }先看上面这段代码首先d对象有几张虚表呢看下面的监视窗口很明显发现d对象有两张虚表但是d对象自己的虚函数func3去哪里了其实它在第一张虚表中我们可以通过上面的代码打印观察出来f()这个地址可以调用说明它一定是函数。这里是可以认为是编译器的监视窗口故意隐藏了func3函数也可以认为是它的一个小bug 可是细心一点发现两张表中的func1地址不一样它们不是都重写了func1函数吗而且用父类指针调用会发现它们调的是同一个函数那么这里为什么地址不一样呢 看下面这个场景   注意这里你要调用的是派生类d对象的func1函数this指针应该指向d对象而这里的ptr1指针恰好指向d对象不需要改动。而ptr2指向的却是Base2对象。调用d对象的func1函数要传d对象的this指针 而不是Base2对象的this指针。所以这里第二张表的地址其实是虚地址多封装了几层是为了修正this指针 接下来我们通过汇编来看看ptr1和ptr2调用的区别更好理解Base2的虚地址 ptr1调用 ptr2调用
http://www.dnsts.com.cn/news/281908.html

相关文章:

  • wordpress建企业网站asp网站建设 win7
  • 北京专业快速建站制作学做网站要多久多少钱
  • 国内外ai设计素材网站国内优秀的网站
  • 网站推广费用预算整合营销传播论文
  • 网站集成微信登陆渭南市住建设局网站
  • 庆阳工程建设网站博客seo优化技术
  • 网站建设案例步骤做网站手机模板app
  • 网站飘落怎么做好的网站制作平台
  • 做网站php和asp哪个好question2answer wordpress 整合
  • 网站备案备注怎么写苏州专业建站
  • 企业网站建设运营方案商洛市建设工程造价管理站网站
  • 做问卷调查的网站wordpress插件有何用
  • 建立个公司网站重庆平台网站建设推荐
  • 龙书浩个人网站学校网站查询
  • 服装织梦网站源码医疗器械经营许可证
  • 西安网站建设方案同城推广有什么平台
  • 中山精品网站建设精英网站建设招标书技术介绍
  • 网站开发美学 2.0微信小程序+网站开发
  • 网站首页设计过程邓亚萍近况 做网站败光20亿
  • 江西住房和城乡建设网站做炫光素材的网站
  • 做网站宽度音乐APP网站开发
  • 保定网站建设报价管理软件是什么
  • 企业网站源码山东省工程建设交易信息网站
  • 网站做美工深圳网站建设哪家
  • 用模板建站做跨境电商的步骤
  • 企业手机网站建设策划书嘉定区整站seo十大排名
  • 廊坊高端品牌网站建设专门做app的网站
  • 如何做汽车的创意视频网站设计汽车之家汽车网
  • 网站开发怎么在页面上调用高德地图显示位置咸宁市做网站
  • 河南建设厅特种工报考网站4000套微信小游戏源码