多态体验,和探索爷爷类指针的多态性

 

1. 多态初体验

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:

    virtual void print()
    {
        cout << "I'm Parent." << endl;
    }
};

class Child : public Parent
{
public:

    void print()
    {
        cout << "I'm Child." << endl;
    }
};

void how_to_print(Parent* p)
{
    p->print();
}

int main()
{
    Parent p;
    Parent*pfather = &p;

    Child c;
    Parent* pson =  reinterpret_cast<Parent*>(&c);
    Parent* p = pson;  // p也具备多态性 

    how_to_print(pfather);
    how_to_print(pson);
    how_to_print(p);

    pson_2 = pfather;
    how_to_print(p);

    return 0;
}

现象:p具备多态性
小结: 指向子类对象的父类指针被传递后,依然具备多态性。

 

2.  探索爷爷类的多态

实验一:

爷爷类(父类的父类)是抽象类,看能否在孙类(子类的子类)身上,实现一个方法(成员函数)的多态调用。

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    virtual void print() = 0;
};

#if 0 // 方式1
class Child : public Parent
{
public:

    virtual void print() = 0;

};
#else // 方式2
class Child : public Parent
{
public:
    void print() {
        cout << "Child: print()" << endl;
    }

};
#endif

class GrandSon : public Child
{
    string name;
public:
    GrandSon(char* n_name)
    {
        name = string(n_name);
    }

    void print()
    {
        cout <<  "GrandSon::print() :" << name << endl;
    }
};

void how_to_print(Parent* p)
{
    p->print();
}

int main()
{
    GrandSon gson1("jason");
    how_to_print(reinterpret_cast<Parent*>(&gson1));
    Parent* pgson1 = reinterpret_cast<Parent*>(&gson1);

    cout << endl;
 
    GrandSon gson2("polly");
    Parent* pgson2 = reinterpret_cast<Parent*>(&gson2);
    how_to_print(pgson2);

    cout << endl;
    // 下面是拓展实验
    Parent* gson_current = pgson1;
    how_to_print(gson_current);

    return 0;
}

小结: 爷爷类(父类的父类)是抽象类时,中间层的父类是抽象类也罢,或者实现了自己的多态方法也罢,此时, 当爷爷类指针指向孙类对象,依然具备多态特性。

 

实验二:

爷爷类(父类的父类)是非抽象类,看能否在孙类(子类的子类)身上,实现一个方法(成员函数)的多态调用。

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    virtual void print() {
        cout << "Parent:: print()" << endl;
    }
};

class Child : public Parent
{
public:
    void print() {
        cout << "Child:: print()" << endl;
    }
};

class GrandSon : public Child
{
    string name;
public:
    GrandSon(char* n_name)
    {
        name = string(n_name);
    }
    void print()
    {
        cout << "GrandSon::print() :" << name << endl;
    }
};

void how_to_print(Parent* p)
{
    p->print();
}

int main()
{
    GrandSon gson1("jason");
    how_to_print(reinterpret_cast<Parent*>(&gson1));
    Parent* pgson1 = reinterpret_cast<Parent*>(&gson1);

    cout << endl;

    GrandSon gson2("polly");
    Parent* pgson2 = reinterpret_cast<Parent*>(&gson2);
    how_to_print(pgson2);

    cout << endl;
    // 下面是拓展实验
    Parent* gson_current = pgson1;
    how_to_print(gson_current);

    return 0;
}

爷爷类是非抽象类,实现了自己的virtual的方法A,且父类也实现了自己的virtual的方法A,且子类也实现了自己的virtual的方法A, 此时, 当爷爷类指针指向孙类对象,依然具备多态特性。 

 

最终结论:

只要调用的成员函数自从爷爷类开始就是virtual修饰的,使用爷爷类的指针指向孙类对象时,就支持多态调用。 

如果你需要一个精简版理解,那么你只需要理解:

多态调用的精髓在于使用了virtual关键字。

 

 

 

 

 

 

.