您的位置:首页 > 编程语言 > C语言/C++

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指针的分步初始化



#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指向父类的虚函数表,
//当父类的虚函数执行完毕时,会再把指针指向子类的虚函数表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: