仮想関数を呼び出す:基本クラスへのポインタまたは参照を介して
#include<iostream>
using namespace std;
class Base
{
public:
virtual void func1()
{
cout << "base::func1()" << endl;
}
virtual void func2()
{
cout << "base::func2()" << endl;
}
virtual void func3()
{
cout << "base::func3()" << endl;
}
void func4()
{
cout << "base::func4()" << endl;
}
private:
int _a;
};
class Dev : public Base
{
public:
virtual void func1()
{
cout << "func1" << endl;
}
virtual void func2()
{
cout << "func2" << endl;
}
virtual void func3()
{
cout << "func3" << endl;
}
void func4()
{
cout << "func4" << endl;
}
};
void TestVirtual(Base* pb)
{
pb->func1();
pb->func2();
pb->func3();
pb->func4();
}
int main()
{
Base a;
Dev b;
TestVirtual(&a);
TestVirtual(&b);
return 0;
}
打印结果:
base::func1()
base::func2()
base::func3()
base::func4()
func1
func2
func3
base::func4()
请按任意键继续. .
#include<iostream>
using namespace std;
class Base
{
public:
void func4()
{
cout << "base::func4()" << endl;
}
};
class Dev : public Base
{
public:
void func4()
{
cout << "func4" << endl;
}
};
void TestVirtual(Base* pb)
{
pb->func4();
}
int main()
{
Base a;
Dev b;
TestVirtual(&b);
return 0;
}
打印结果:
base::func4()
何多型が存在しないときに発生ポインタを使用する場合、ベース・クラス・オブジェクトに対する今回のサブクラスへのポインタまたは参照を使用して、唯一の基本クラスを呼び出します。
3つのベース・クラス、仮想関数が存在する場合、3つのベース・クラス、仮想関数書き換えのサブクラスに加えて、基本クラスへのポインタまたは参照を使用して、この時間を、共通関数自分自身を追加したときに指示物体のサブクラス3つのサブクラスの機能をオーバーライドするには、基本クラスの使用ダイレクトコールへのポインタで、一般的には、基本クラスのサブクラスでは、関数を呼び出す方法がない場合は、基本クラスは、通常の関数ではないので、通話時間へのポインタを使用して、この時間。
関数は、同じ名前のベース・クラスとサブクラスを有する場合、この時点で発生する(上書き)を書き換えることで、オブジェクトのサブクラスに蓄積ポインタの使用は、その後、基本クラスを呼び出す同じ名前の関数ではなく、サブクラスでA。
================================================== ===================================
機能は、多形性の原則を呼び出す:
親クラスのサブクラスで発生しますこれは、オブジェクトの基本クラスへのポインタまたは参照を使用しているときだけ関数呼び出しが基本クラス、サブクラスであり、通話をしない場合のように(上書き)書き換え同じ名前の関数であります
================================================== ===================================
多重継承仮想テーブルのビルドプロセス:
ポリモーフィックカテゴリー:
静态多态:静态绑定/早绑定在编译阶段就可以确定具体调用哪个函数(函数重载 + 模板)
动态多态:动态多态/晚绑定在编译阶段无法确定具体的调用,需要在运行时才能确定具体的调用(虚函数+继承实现),原因是在编译阶段无法确定基类的指针或者引用指向的哪一个子类的对象。
内联函数不能作为虚函数:
原因,假设已经是内联函数,在编译阶段,会将该函数展开,如果展开,就不会通过虚表去调用,就是不能实现多态了
静态的成员函数不能作为虚函数:
因为通过类名来调用静态成员函数的时候,根本找不到虚表,也就无法调用。最重要的一点就是,静态成员函数没有this指针。
构造函数也不能作为虚函数构造函数也是不能用const来修饰的
原因:一个类中如果包含虚函数,那么该类的构造函数有两个作用一个是初始化类中的成员变量,另一个就是在初始化列表的位置,由编译器将虚表的指针填充在对象的前4个字节里面。也就是说虚表的构造需要由构造函数参与,先有构造函数,才有虚表。没有构造函数就没有虚表,假如将构造函数给成虚函数,那么就需要通过虚表去调用构造函数,此时虚表在哪里呢?由此可以知道构造函数不能作为虚函数
析构函数可以作为虚函数
构造函数可以重载,析构函数不可以
析构函数是重写的一种特例
=====================================================================================
静的タイプ:タイプは、変数宣言
コンパイル時に機能を
動的型:実際の基準(点)の種類をされている
実行時に決定クラス仮想関数呼び出し
それは、このようなアプリケーション・ヒープ・スペースからサブクラスなどの派生クラス動的なリソース管理、に来る場合は、基本クラスのデストラクタ仮想関数セットは、それが推奨されている場合:仮想関数、またはそれに蓄積さデストラクタ最高メモリリークがあるかもしれません。
#include<iostream>
using namespace std;
class A
{
public:
A()
{}
virtual ~A()
{
cout << "A::~A()" << endl;
}
};
class B : public A
{
public:
B(int num)
{
_p = new int(num);
}
~B()
{
delete _p;
cout << "B::~B()" << endl;
}
int* _p;
};
void func()
{
B b(10);
A& a = b;
}
int main()
{
A* a = new B(10);
delete a;
return 0;
}
仮想関数呼び出しと高速で、通常の関数を呼び出す:
トップため、より高速な正常な機能を
普通函数(指非虚函数)调用:
1.传参(如果有参数)
2.通过call指令调用该函数(call函数入口地址)
虚函数调用:
1.没有完全实现多态条件,比如:没有通过基类的指针或者引用调用虚函数,与普通的函数调用相同
2.多态的实现条件完全满足:
a>>从对象的前四个字节中取虚表的地址
b>>传参,包括this指针
c>>从虚表中获取虚函数地址
d>>调用虚函数
動的多型虚血:の走行速度を減少させることができる
静的マルチステート、マルチ状態ダイナミックました:
#include<iostream>
using namespace std;
class A
{
public:
A()
{}
virtual ~A()
{
cout << "A::~A()" << endl;
}
};
class B : public A
{
public:
B(int num)
{
_p = new int(num);
}
~B()
{
delete _p;
cout << "B::~B()" << endl;
}
int* _p;
};
void func(A* a)
{
a = new B(10); //动态多态
}
int main()
{
A* a = new B(10); //静态多态
func(new B(20));//动态多态,函数调用参数在运行时才会传递,才会确定积累的指针或者引用到底指向哪个子类对象
delete a;
return 0;
}
仮想テーブルは、その段階で生成されますか?
コンパイル相
メモリ領域に格納される仮想テーブル:
スニペット
インサート:
最大公約数:
int gcd(int m, int n)
{
if (n == 0)
return m;
if(m < n)
swap(m,n);
int temp = m%n;
m = n;
n = temp;
return gcd(m, n);
}