c++中的多态和vptr指针
2018-04-08 21:47
190 查看
1.多态原理探究#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//01
//多态原理探究
//要有继承 虚函数重写 父类指针指向子类对象
class Parent
{
public:
Parent(int a = 0)
{
this->a = a;
}
virtual void print()//动手脚 写virtual关键字,c++编译器会做特殊处理
{
cout << "parent" << endl;
}
virtual void print2()//动手脚 写virtual关键字,c++编译器会做特殊处理
{
cout << "parent2" << endl;
}
private:
int a;
};
class Child:public Parent
{
public:
Child(int a = 0, int b = 0) :Parent(a)
{
this->b = b;
}
virtual void print()//动手脚 写virtual关键字 c++编译器会做特殊处理
{
cout << "Child" << endl;
}
private:
int b;
};
void howToPlay(Parent *base)
{
base->print();//有多态发生,动手脚
//效果:传来子类就执行子类的成员函数 传来父类就执行父类的成员函数
//看起来像是c++编译器能够识别父类对象和子类对象,但是实际c++编译器不需要区分子类对象,都是vptr指针搞的鬼
//父类对象和子类对象分别有自己的vptr指针, =》虚函数表=》函数入口地址
//迟绑定(函数运行时,编译器才回去判断)
}
int main()
{
Parent p1;//动手脚(提前布局),用类定义对象的时候,c++编译器会在对象中添加一个vptr指针
Child c1;//定义子类对象的时候也会添加一个vptr指针
howToPlay(&p1);
howToPlay(&c1);
system("pause");
return 0;
}
运行结果:Parent
Child
2.证明vptr指针的存在#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//02
//证明vptr指针的存在
class Parent1
{
public:
Parent1(int a = 0)
{
this->a = a;
}
void print()
{
cout << "Parent1(不是虚函数)" << endl;
}
private:
int a;
};
class Parent2
{
public:
Parent2(int a = 0)
{
this->a = a;
}
virtual void prite()
{
cout << "Parent2(虚析构函数)" << endl;
}
private:
int a;
};
int main02()
{
printf("sizeof(Parent1):%d sizeof(Parent2):%d\n", sizeof(Parent1), sizeof(Parent2));
system("pause");
return 0;
}
//运行结果:sizeof(Parent1):4 sizeof(Parent2):8
//说明vptr的确存在,大小为4
3.vptr指针的分步初始化
![](https://img-blog.csdn.net/2018040821333558)
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//03
//指针的分布初始化
//构造函数中调用虚函数能发生多态么?也就是说,初始化子类对象时候会先调用父类的构造函数,
//父类的构造函数中又有一个虚函数,此时这个虚函数是执行的子类的函数还是父类的函数
class parent
{
public:
parent(int a = 0)
{
this->a = a;
print();
}
virtual void print()
{
cout << "parent print" << endl;
}
private:
int a;
};
class child :public parent
{
public:
child(int a = 0, int b = 0) :parent(a)
{
this->b = b;
print();
}
virtual void print()
{
cout << "child print" << endl;
}
private:
int a;
int b;
};
void playObj(parent *base)
{
base->print();
}
int main()
{
child c1;//定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?
system("pause");
return 0;
}
//运行结果:parent print
// child print
//没有发生多态
//原因:child c1;//在定义对象的时候要初始化c1.vptr指针,初始化是分步惊醒的
//当执行父类的构造函数时,c1.vptr指向父类的虚函数表,
//当父类的虚函数执行完毕时,会再把指针指向子类的虚函数表
#include<cstdlib>
#include<cstring>
using namespace std;//01
//多态原理探究
//要有继承 虚函数重写 父类指针指向子类对象
class Parent
{
public:
Parent(int a = 0)
{
this->a = a;
}
virtual void print()//动手脚 写virtual关键字,c++编译器会做特殊处理
{
cout << "parent" << endl;
}
virtual void print2()//动手脚 写virtual关键字,c++编译器会做特殊处理
{
cout << "parent2" << endl;
}
private:
int a;
};
class Child:public Parent
{
public:
Child(int a = 0, int b = 0) :Parent(a)
{
this->b = b;
}
virtual void print()//动手脚 写virtual关键字 c++编译器会做特殊处理
{
cout << "Child" << endl;
}
private:
int b;
};
void howToPlay(Parent *base)
{
base->print();//有多态发生,动手脚
//效果:传来子类就执行子类的成员函数 传来父类就执行父类的成员函数
//看起来像是c++编译器能够识别父类对象和子类对象,但是实际c++编译器不需要区分子类对象,都是vptr指针搞的鬼
//父类对象和子类对象分别有自己的vptr指针, =》虚函数表=》函数入口地址
//迟绑定(函数运行时,编译器才回去判断)
}
int main()
{
Parent p1;//动手脚(提前布局),用类定义对象的时候,c++编译器会在对象中添加一个vptr指针
Child c1;//定义子类对象的时候也会添加一个vptr指针
howToPlay(&p1);
howToPlay(&c1);
system("pause");
return 0;
}
运行结果:Parent
Child
2.证明vptr指针的存在#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//02
//证明vptr指针的存在
class Parent1
{
public:
Parent1(int a = 0)
{
this->a = a;
}
void print()
{
cout << "Parent1(不是虚函数)" << endl;
}
private:
int a;
};
class Parent2
{
public:
Parent2(int a = 0)
{
this->a = a;
}
virtual void prite()
{
cout << "Parent2(虚析构函数)" << endl;
}
private:
int a;
};
int main02()
{
printf("sizeof(Parent1):%d sizeof(Parent2):%d\n", sizeof(Parent1), sizeof(Parent2));
system("pause");
return 0;
}
//运行结果:sizeof(Parent1):4 sizeof(Parent2):8
//说明vptr的确存在,大小为4
3.vptr指针的分步初始化
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;//03
//指针的分布初始化
//构造函数中调用虚函数能发生多态么?也就是说,初始化子类对象时候会先调用父类的构造函数,
//父类的构造函数中又有一个虚函数,此时这个虚函数是执行的子类的函数还是父类的函数
class parent
{
public:
parent(int a = 0)
{
this->a = a;
print();
}
virtual void print()
{
cout << "parent print" << endl;
}
private:
int a;
};
class child :public parent
{
public:
child(int a = 0, int b = 0) :parent(a)
{
this->b = b;
print();
}
virtual void print()
{
cout << "child print" << endl;
}
private:
int a;
int b;
};
void playObj(parent *base)
{
base->print();
}
int main()
{
child c1;//定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?
system("pause");
return 0;
}
//运行结果:parent print
// child print
//没有发生多态
//原因:child c1;//在定义对象的时候要初始化c1.vptr指针,初始化是分步惊醒的
//当执行父类的构造函数时,c1.vptr指向父类的虚函数表,
//当父类的虚函数执行完毕时,会再把指针指向子类的虚函数表
相关文章推荐
- C++基础7【难】 多态:实现原理 vptr指针 证明vptr存在 类的步长 纯虚函数:抽象类 案例 【面试题】
- 深入剖析C++多态、VPTR指针、虚函数表
- C/C++—— 在构造函数中调用虚函数能实现多态吗(Vptr指针初始化的过程分析)
- C++之this指针与另一种“多态”
- C++中的 虚表(vtable)和虚指针(vptr)
- 虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数、C++对象模型图
- C++多态实现中的指针修正
- C++ 多态问题:为什么不直接用子类引用子类,而是用父类指针指向子类
- C++之this指针与另一种“多态”
- C++智能指针与类继承多态
- c++父类指针强制转为子类指针后的测试(帮助理解指针访问成员的本质)(反多态)
- C++ 多态 指针转换
- C++多态中的实现要用指针,而不是虚基类(接口)的对象
- 【c++】指针和引用实现多态
- more effective c++ 第一章读书笔记: 指针,引用,c++类型转换,多态数组,默认构造函数
- 多态原理探究_证明vptr指针的存在
- C++之this指针与另一种“多态”
- C++基础8【难】 回顾:数组指针,函数指针,函数指针做函数参数 C语言多态
- C++多态中的实现要用指针,而不是虚基类(接口)的对象
- C++多态:虚函数、指针、虚函数表