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++中是一个重要的概念,通过虚函数机制实现了在程序运行时根据调用对象来判断具体调用哪一个函数. 具体来说就是:父类类别的指针(或者引用)指向其子类的实例,然后通过父类的指针(或者引用)调用实际 ...
随机推荐
- ubuntu windows mutual remote control
Win10 remote control Ubuntu18 Part1.ubuntu settings 1.安装所需组件 sudo apt-get update //若没有desktop sharin ...
- win到linux的编码问题
从windows到linux的文件可能存在编码问题时,这是因为,Linux和Windows文本文件的行结束标志不同.在Linux中,文本文件用"\n"表示回车换行,而Windows ...
- TensorFlow2.0
安装开发环境 1.首先安装 anaconda(https://www.anaconda.com/) 2.修改anaconda的镜像源 conda config --add channels https ...
- Spring Cloud第二篇 | 使用并认识Eureka注册中心
本文是Spring Cloud专栏的第二篇文章,了解前一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 一.Sprin ...
- 目不识丁的我使用Python编写汉字注音小工具
一万点暴击伤害 人懒起来太可怕了,放了个十一充分激发了我的惰性.然后公众号就这么停了半个月,好惭愧- 新学期儿子的幼儿园上线了APP,每天作业通过app布置后,家长需要陪着孩子学习,并上传视频才算完成 ...
- 漫谈边缘计算(三):5G的好拍档
边缘计算的热度迅速攀升,还有一个不得不提的因素,就是5G的发展. [5G推动云计算从集中化向分布式演进] 在第一篇文章(<漫谈边缘计算(一):边缘计算是大势所趋>)中我提到,传统的云计算技 ...
- CentOS 7 安装并配置 MySQL 5.7
Linux使用MySQL Yum存储库上安装MySQL 5.7,适用于Oracle Linux,Red Hat Enterprise Linux和CentOS系统. 1.添加MySQL Yum存储库 ...
- Unity 3D中C#的性能优化小陷阱
本篇内容主要来自Unity官方手册: 一般性能优化 一些地方为本人瞎编杜撰,请酌情参考.如有错误,欢迎指出. Unity里C#编程虽然既简单还很爽,但是性能小陷阱还不少.我总强迫自己让代码最优,因此很 ...
- 阿里巴巴主导的“华山版《Java 开发手册》”简介
1."83行代码计划"项目介绍(转自github): 2018年9月22日,在2018杭州云栖大会上,召开<码出高效:Java 开发手册>新书发布会,并宣布将图书所有收 ...
- SpringBoot添加热部署
一.导入依赖 <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> & ...