OOP 一些例题

ops/2024/10/30 20:06:03/

例题一

#include <iostream>
using namespace std;class Animal
{
public:Animal(string name) :name_(name) {}virtual void bark() = 0;
protected:string getName() { return name_; }
private:string name_;
};class Cat : public Animal {
public:Cat(string name) : Animal(name){}void bark() {cout << "Cat " << getName() << "miao miao miao" << endl;}
};
class Dog : public Animal {
public:Dog(string name) : Animal(name) {}void bark() {cout << "Dog " << getName() << "wang wang wang" << endl;}
};
int main()
{Animal* cat = new Cat("罗小黑");Animal* dog = new Dog("布鲁托");int* p = (int*)cat;int* q = (int*)dog;int tmp = p[0];p[0] = q[0];q[0] = tmp;cat->bark();dog->bark();
}

运行结果: Dog 罗小黑wang wang wang
Cat 布鲁托miao miao miao

原因:将Cat与Dog的虚表指针vfptr交换了,导致调用的函数互换了

例题二

class Base {
public:virtual void show(int i = 10){cout << "Base::show() " << i << endl;}
};class Drived : public Base
{
public:virtual void show(int i = 20){cout << "Drived::show() " << i << endl;}
};
int main()
{Base* b = new Drived;b->show();
}

运行结果 Drived::show() 10

原因:编译阶段,会将基类的show()函数,如果该函数有默认形参那么将其形参默认值入栈。但是运行时期,是调用的虚函数表的函数地址。

具体汇编代码如下,

b->show();
00007FF66DED2692  mov         rax,qword ptr [b]  
00007FF66DED2696  mov         rax,qword ptr [rax]  
00007FF66DED2699  mov         edx,0Ah   // 基类的show()默认形参10
00007FF66DED269E  mov         rcx,qword ptr [b]  
00007FF66DED26A2  call        qword ptr [rax]

例题三


class Base {
public:virtual void show(){cout << "Base::show() " << endl;}
};class Drived : public Base
{
private:virtual void show(){cout << "Drived::show() " << endl;}
};
int main()
{Base* b = new Drived;b->show();delete b;
}

运行结果Drived::show()

原因编译阶段,编译器首先是否拥有函数访问权限。代码中,使用的是基类指针,所以编译器检查的是基类中show()的权限。而具体调用的show()是在运行阶段,因为基类使用虚函数,所以调用show()的时候动态绑定。尽管派生类的show()函数是私有的,但是其地址是在虚函数表中,因此从虚表中调用派生类的show()函数。

例题四

class Base {
public:Base(){cout << "Base Construct" << endl;clear();}void clear(){memset(this, 0, sizeof(*this));}virtual void show(){cout << "Base::show() " << endl;}
};class Drived : public Base
{public:Drived() {cout << "Drived Construct" << endl;}virtual void show(){cout << "Drived::show() " << endl;}
};
int main()
{/*Base* b1 = new Base(); // 运行错误b1->show();*/Base* b2 = new Drived;   // 运行失败b2->show();
}

http://www.ppmy.cn/ops/129685.html

相关文章

MFC图形函数学习04——画矩形函数

MFC中绘制矩形函数是MFC的基本绘图函数&#xff0c;它的大小和位置由左上角和右下角的坐标决定&#xff1b;若想绘制的矩形边框线型、线宽、颜色以及填充颜色都还需要其它函数的配合。 一、绘制矩形函数 原型&#xff1a;BOOL Rectangle(int x1,int y1,int x2,int y2); …

分别用webpack和vite注册全局组件

基础组件的自动化全局注册 1. 组件全部导入后&#xff0c;批量注册 import dgDialog from "/components/dgDialog/index.vue"; import svgIcon from "/components/svgIcon/index.vue"; const allComponent { dgDialog, svgIcon }; export default {inst…

Python实现基于WebSocket的stomp协议调试助手工具

stomp协议很简单&#xff0c;但是搜遍网络竟没找到一款合适的客户端工具。大多数提供的都是客户端库的使用。可能是太简单了吧&#xff01;可是即便这样&#xff0c;假如有一可视化的工具&#xff0c;将方便的对stomp协议进行抓包调试。网上类似MQTT的客户端工具有很多&#xf…

如何从iconfont中获取字体图标并应用到微信小程序中去?

下面我们一一个微信小程序的登录界面的制作为例来说明&#xff0c;如何从iconfont中获取字体图标是如何应用到微信小程序中去的。首先我们看效果。 这里所有的图标&#xff0c;都是从iconfont中以字体的形式来加载的&#xff0c;也就是说&#xff0c;我们自始至终没有使用一张…

工具_Nginx

文章目录 location语法介绍跨域配置https配置http重定向到https配置反向代理配置负载均衡配置upstream配置负载均衡算法&#xff08;1&#xff09;rr轮询&#xff08;默认&#xff09;&#xff08;2&#xff09;wrr加权轮询&#xff08;weight&#xff09;&#xff08;3&#x…

[极客大挑战 2019]FinalSQL

首先进入题目正常思路是登录框存在sql注入&#xff0c;尝试万能密码&#xff0c;提示“你可别被我逮住了&#xff0c;臭弟弟”&#xff0c;应该是被过滤了&#xff0c;做一下FUZZ测试&#xff0c;发现过滤了空格&#xff0c;union等关键字 FUZZ字典已经上传到CSDN了 试了很长时…

没有基础,学习HCIE难吗?

首先要清楚&#xff0c;华为 HCIE-Datacom 认证并非局限于特定专业背景&#xff0c;即便对专业基础有一定要求&#xff0c;无论你有无相关学习经历或者工作经验&#xff0c;皆有机会报考并争取通过这一认证。HCIE-Datacom 考试主要由笔试和实验两部分构成&#xff0c;涉及高级路…

【Python爬虫实战】络爬虫完整指南:从TCP/IP协议到爬虫实践

网络爬虫完整指南&#xff1a;从TCP/IP协议到爬虫实践 什么是TCP/IP协议&#xff1f; TCP/IP协议&#xff08;传输控制协议/互联网协议&#xff09; 是互联网通信的核心协议套件&#xff0c;它定义了设备在互联网上如何通信的规则和方式。TCP/IP协议由多个层组成&#xff0c;其…