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;
}
相關文章
相關標籤/搜索