c++-多态和vptr指针
多态的原理
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(int a) {
this->a = a;
}
virtual void func(int a)
{
cout << "Parent::func(int)..." << endl;
}
virtual void func(int a, int b, int c)
{
cout << "Parent::func(int ,int ,int )...." << endl;
}
private:
int a;
};
class Child :public Parent
{
public:
Child(int a, int b) :Parent(a)
{
this->b = b;
}
virtual void func(int a)
{
cout << "Child: func(int)..." << endl;
}
void func(int a, int b) {
cout << "Child :func(int ,int )..." << endl;
}
virtual void func(int a, int b, int c)
{
cout << "Child ::func(int ,int ,int )..." << endl;
}
private:
int b;
};
void myFunc(Parent *pp)
{
pp->func(10);
}
int main(void)
{
//Parent *pp = new Parent(10);
//Parent *cp = new Child(100, 200);
Parent *pp = new Child(100, 200);
pp->func(10);//Parent ? Child
//如果调用一个普通函数,编译器根本就不会查找虚函数表。
//只有你调用的函数,是虚函数的时候,才会去查找虚函数表
// myFunc(pp);
pp->func(10, 20, 30);
return 0;
}
验证vptr指针的存在
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Parent
{
public:
virtual void func()
{
cout << "Parent::func().." << endl;
}
virtual void func(int a)
{
cout << "Parent::func().." << endl;
}
private:
int a;
};
class Parent2
{
public:
void func()
{
cout << "Parent2::func().." << endl;
}
private:
int a;
};
int main(void)
{
Parent p1;
Parent2 p2;
cout << "sizeof(p1) " << sizeof(p1) << endl;//多出来的4个字节就是vptr指针所占用的空间。
cout << "sizeof(p2) " << sizeof(p2) << endl;
return 0;
}
vptr指针分布初始化
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(int a)
{
cout << "Parent(int ..)" << endl;
this->a = a;
//print();//是调用父类的print() 还是 子类的print()?
//通过结果 此时调用的父类的print 并不是子类的print
}
virtual void print()
{
cout << "Parent::print()...a = "<<a << endl;
}
private:
int a;
};
class Child :public Parent
{
public:
Child(int a, int b) :Parent(a) //在调用父类的构造器的时候,会将vptr指针当做父类来处理。
//此时会临时指向父类的虚函数表
{
//将子类对象的空间有编程子类对象处理,vptr指针就从指向父类的表 变成 指向子类的表
cout << "Child (int ,int )" << endl;
this->b = b;
print();//此时vptr指针已经回到了 子类的表, 调用的是子类的print函数。
}
virtual void print() {
cout << "Child ::Print()..b = " << b << endl;
}
private:
int b;
};
int main(void)
{
Parent *pp = new Child(10, 20);
// pp->print();//发生多态
delete pp;
return 0;
}
父类指针和子类指针的步长
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(int a)
{
this->a = a;
}
virtual void print()
{
cout << "Parent::print a= " << a << endl;
}
int a;
};
class Child :public Parent
{
public:
Child(int a) :Parent(a)
{
}
virtual void print()
{
cout << "Child::print a= " << a << endl;
}
int b;
};
int main(void)
{
Child array[] = { Child(0), Child(1), Child(2) };
Parent *pp = &array[0];
Child *cp = &array[0];
pp++;
pp->print();
cp->print();
#if 0
pp++;//pp +sizeof(Parent)
cp++;//cp +sizeof(Child)
pp->print();
cp->print();
#endif
cout << "-----" << endl;
int i = 0;
for (cp= &array[0], i = 0; i < 3; i++, cp++) {
cp->print();
}
return 0;
}
c++-多态和vptr指针的更多相关文章
- 深入剖析C++多态、VPTR指针、虚函数表
在讲多态之前,我们先来说说关于多态的一个基石------类型兼容性原则. 一.背景知识 1.类型兼容性原则 类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代.通过公有继承,派 ...
- c++多态之——vptr指针
之前做过一个测试,在一个类中定义一个virtual修饰的函数时,sizeof这个类,发现类的大小多了恰好一个指针的字节大小,当初不明白,只是记住有这么一个特性.后来,发现它就是c++编译器给我们添加的 ...
- 这里面盲点很多,构造函数的调用问题,还有vptr指针的++问题(已解决)
#include<iostream> //实现vptr指针初始化问题 using namespace std; class Father { public: Father (int f) ...
- 关于vptr指针初始化的分步
vptr:一个具有虚函数类的对象所具有的隐藏的成员,指向该类的虚函数表. 父类对象的vptr指向是一直指向父类的.但子类的vptr指针最终是指向子类的, 当子类创建的时候,先调用父类构造函数,这个时候 ...
- 53)vptr指针的分布初始化
1)一个父类: 2)一个子类: 3)我的main函数内容 4)通过结果证明 那么产生了问题,这个print是一个虚函数,不应该 在 我的main函数中 通过调用pp->print,在pr ...
- 虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?
五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的 ...
- 关于函数指针与c++多态
原文 https://www.cnblogs.com/zhchngzng/p/4013031.html 虚函数是实现多态的重要元素,请看: class A { public: void a0(){c ...
- c++编译器对多态的实现原理总结
问题:定义一个空的类型,里面没有任何的成员变量或者成员函数,对这个类型进行 sizeof 运算,结果是? 结果是1,因为空类型的实例不包含任何信息,按道理 sizeof 计算之后结果是0,但是在声明任 ...
- C++ 多态的实现原理与内存模型
多态在C++中是一个重要的概念,通过虚函数机制实现了在程序运行时根据调用对象来判断具体调用哪一个函数. 具体来说就是:父类类别的指针(或者引用)指向其子类的实例,然后通过父类的指针(或者引用)调用实际 ...
随机推荐
- (二)OpenStack---M版---双节点搭建---数据库安装和配置
↓↓↓↓↓↓↓↓视频已上线B站↓↓↓↓↓↓↓↓ >>>>>>传送门 本章节只在Controller节点执行 1.安装Mariadb数据库来存储信息 2.NoSQL数 ...
- Reactor和Proactor模型
背景 前面介绍了I/O多路复用模型,那有了I/O复用,有了epoll已经可以使服务器并发几十万连接的同时,还能维持比较高的TPS,难道还不够吗?比如现在在使用epoll的时候一般都是起个任务,不断的去 ...
- leetcode 114二叉树转换成链表
解法一 可以发现展开的顺序其实就是二叉树的先序遍历.算法和 94 题中序遍历的 Morris 算法有些神似,我们需要两步完成这道题. 将左子树插入到右子树的地方 将原来的右子树接到左子树的最右边节点 ...
- Netty网络框架
Netty网络框架 Netty是一个异步的基于事件驱动的网络框架. 为什么要使用Netty而不直接使用JAVA中的NIO 1.Netty支持三种IO模型同时支持三种Reactor模式. 2.Netty ...
- EntityFramework Core 3多次Include导致查询性能低之解决方案
前言 上述我们简单讲解了几个小问题,这节我们再来看看如标题EF Core中多次Include导致出现性能的问题,废话少说,直接开门见山. EntityFramework Core 3多次Include ...
- JS进阶面试题整理(仅仅整理我做错的题)
前几天看到掘金博客一篇文章,找到了这个JavaScript进阶问题列表:现在把地址贴出来,想找工作或者想要巩固自己JS的同学可以参考 该文档会不定时更新 一.箭头函数 箭头函数相当于匿名函数,并 ...
- Selenium+Java(十一)Selenium窗口切换
前言: Selenium在当前页面调整到新页面时打开了新的窗口,此时就需要跳转到新的窗口去,需要把窗口进行切换. 获取窗口句柄方法: 获取所有: //获取所有窗口句柄,返回的是set类型 driver ...
- vCenter Server Appliance(VCSA )6.7部署指南
目录 简介 环境准备 开始安装 第一阶段安装 第二阶段安装 使用 简介 早期的VCSA支持 SUSE 和 Windows,不太懂SUSE,也不想用Windows 而在2018年4月17日VCSA 6. ...
- 【JMX】jmx结合jmx_exporter实现promethues监控
JMX JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展.这种机制可以方便的管理.监控正在运行中的Java程序.常用于管理线程,内存,日志Lev ...
- Tomcat eclipse 启动时一个工程影响另一个工程
两个project:A, B; 工程 A 的 Jersey 服务是正常的, 工程 B 的 Jersey 服务是不正常的:如果工程 B 不存在的话, 工程 A 的 Jersey 服务可以在 Tomca ...