仮想関数の役割
キーワードは、仮想仮想関数と呼ばれる関数があり、仮想関数および仮想継承が同じ、仮想関数ではありません多状態考え方で重要な概念です。プログラムは、適切なメンバ関数の動的選択で実行されている場合を意味結合ダイナミックを達成するために、仮想機能の役割。異なるオブジェクトの基本クラスのポインタ(参照すぎる)点、メンバ関数の同じ名前が異なる結果を示します。
仮想関数の使用
唯一の感謝、ここではコンノート・パークのブログ記事を描く https://www.cnblogs.com/weiyouqing/p/7544988.htmlを(記事URL)
#include <iostream>
using namespace std;
class Parent
{
public:
char data[20];
void Function1();
virtual void Function2(); // 这里声明Function2是虚函数
}parent;
void Parent::Function1()
{
printf("This is parent,function1\n");
}
void Parent::Function2()
{
printf("This is parent,function2\n");
}
class Child :public Parent
{
void Function1();
void Function2();
} child;
void Child::Function1()
{
printf("This is child,function1\n");
}
void Child::Function2()
{
printf("This is child,function2\n");
}
void fun(Parent & p) //这是引用的方法
{
p.Function1();
p.Function2();
}
int main(int argc, char* argv[])
{
Parent *p;
cout << "父类指针指向子类对象的情况" << endl;
p = &child;
p->Function1();
p->Function2();
cout << "父类指针指向父类对象的情况" << endl;
p = &parent;
p->Function1();
p->Function2();
fun(child);
fun(parent);
return 0;
}
クラスは、レイアウトの予備的な理解内の仮想機能を持っています
ここでは私の感謝の気持ちを表現するために、ショック記事に対するココナッツガードを食べるCSDNに描く https://blog.csdn.net/lyztyycode/article/details/81326699
観察による工具VS内のクラス構造。
#include <iostream>
using namespace std;
class Parent //父类
{
public:
int a;
virtual void Function1();
virtual void Function2();
virtual void Function3();
}parent;
void Parent::Function1()
{
printf("This is parent,function1\n");
}
void Parent::Function2()
{
printf("This is parent,function2\n");
}
void Parent::Function3()
{
printf("This is parent,function3\n");
}
class Parent2 //父类2
{
public:
int a;
virtual void Function1();
virtual void Function2();
virtual void Function3();
}parent2;
void Parent2::Function1()
{
printf("This is parent,function1\n");
}
void Parent2::Function2()
{
printf("This is parent,function2\n");
}
void Parent2::Function3()
{
printf("This is parent,function3\n");
}
class Child :public Parent ,public Parent2 //子类
{
virtual void Function1();
virtual void Function5();
} child;
void Child::Function1()
{
printf("This is child,function4\n");
}
void Child::Function5()
{
printf("This is child,function5\n");
}
int main(int argc, char* argv[])
{
return 0;
}
//下面是不同情况的子类内部空间布局
一般继承没有虚函数覆盖的情况
父类中有虚函数 Function1 Function2 Function3
子类中有虚函数 Function4 Function5
/*
1>class Child size(8):
1> +---
1> 0 | +--- (base class Parent)
1> 0 | | {vfptr}
1> 4 | | a
1> | +---
1> +---
1>
1>Child::$vftable@:
1> | &Child_meta
1> | 0
1> 0 | &Parent::Function1
1> 1 | &Parent::Function2
1> 2 | &Parent::Function3
1> 3 | &Child::Function4
1> 4 | &Child::Function5
1>
1>Child::Function4 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/
一般继承有虚函数覆盖的情况
父类有虚函数 Function1 Function2 Function3
子类有虚函数 Function1 Function5
/*
1>class Child size(8):
1> +---
1> 0 | +--- (base class Parent)
1> 0 | | {vfptr}
1> 4 | | a
1> | +---
1> +---
1>
1>Child::$vftable@:
1> | &Child_meta
1> | 0
1> 0 | &Child::Function1
1> 1 | &Parent::Function2
1> 2 | &Parent::Function3
1> 3 | &Child::Function5
1>
1>Child::Function1 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/
多继承但是父类虚函数没有被覆盖的情况
父类1有虚函数 Function1 Function2 Function3
父类2有虚函数 Function1 Function2 Function3
子类有虚函数 Function4 Function5
/*
1>class Child size(16):
1> +---
1> 0 | +--- (base class Parent)
1> 0 | | {vfptr}
1> 4 | | a
1> | +---
1> 8 | +--- (base class Parent2)
1> 8 | | {vfptr}
1>12 | | a
1> | +---
1> +---
1>
1>Child::$vftable@Parent@:
1> | &Child_meta
1> | 0
1> 0 | &Parent::Function1
1> 1 | &Parent::Function2
1> 2 | &Parent::Function3
1> 3 | &Child::Function4
1> 4 | &Child::Function5
1>
1>Child::$vftable@Parent2@:
1> | -8
1> 0 | &Parent2::Function1
1> 1 | &Parent2::Function2
1> 2 | &Parent2::Function3
1>
1>Child::Function4 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/
多继承且父类虚函数有被覆盖的情况
父类1有虚函数 Function1 Function2 Function3
父类2有虚函数 Function1 Function2 Function3
子类有虚函数 Function1 Function5
/*
1>class Child size(16):
1> +---
1> 0 | +--- (base class Parent)
1> 0 | | {vfptr}
1> 4 | | a
1> | +---
1> 8 | +--- (base class Parent2)
1> 8 | | {vfptr}
1>12 | | a
1> | +---
1> +---
1>
1>Child::$vftable@Parent@:
1> | &Child_meta
1> | 0
1> 0 | &Child::Function1
1> 1 | &Parent::Function2
1> 2 | &Parent::Function3
1> 3 | &Child::Function5
1>
1>Child::$vftable@Parent2@:
1> | -8
1> 0 | &thunk: this-=8; goto Child::Function1
1> 1 | &Parent2::Function2
1> 2 | &Parent2::Function3
1>
1>Child::Function1 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/