1. 程式人生 > >C++總結6——繼承與多型的筆試題【轉】

C++總結6——繼承與多型的筆試題【轉】

1—————————————————

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int data):_ma(data)  
    {
        cout<<"Base()"<<endl;
    }
    virtual ~Base()  
    {
        cout<<"~Base()"<<endl;
    }
    virtual void Show(int i= 10)//虛擬函式
    {
        cout<<"Base::Show(), i="<<i<<endl;
    }
private:
    int _ma;
};

class Derive : public Base
{
public:
    Derive(int data1, int data2):Base(data1),_mb(data2)  
    {
        cout<<"Derive()"<<endl;
    }
    ~Derive()  
    {
        cout<<"~Derive()"<<endl;
    };
    virtual void Show(int i= 20)//虛擬函式
    {
        cout<<"Derive::Show(), i="<<i<<endl;
    }
private:
    int _mb;
};

int main()
{
    Base *p = new Derive(10,10);
    p->Show();
    delete p;

    return 0;
}

p->Show();函式有預設的引數,在呼叫過程中沒有傳遞引數。編譯期進行形參壓棧,已經將基類的Show()函式的10壓進棧了,呼叫派生類中的Show時,不再對其進行初始化。若要對虛擬函式中的值進行賦值,不要在基類虛擬函式的引數列表中賦預設值。

2.———————————————————————

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int data):_ma(data)  
    {
        cout<<"Base()"<<endl;
    }
    virtual ~Base()
    {
        cout<<"~Base()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Base::Show()"<<endl;
    }
    void Show(int i)
    {
        cout<<"Base:Show(int)"<<endl;
    }
private:
    int _ma;
};

class Derive : public Base
{
public:
    Derive(int data1, int data2):Base(data1),_mb(data2)  
    {
        cout<<"Derive()"<<endl;
    }
    ~Derive()  
    {
        cout<<"~Derive()"<<endl;
    }
private:
    virtual void Show()
    {
        cout<<"Derive::Show()"<<endl;
    }
private:
    int _mb;
};

int main()
{
    Base *p = new Derive(10,20);
    p->Show();
    delete p;

    return 0;
}

在編譯時,發現是基類的指標指向派生類的物件,並且該基類中有虛擬函式,故採用動態繫結。在執行時,Derive呼叫自己的私有Show()函式。

3.—————————————————————-

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int data):_ma(data)  
    {
        cout<<"Base()"<<endl;
        Clear();
    }
    void Clear()
    {
        memset(this, 0 ,sizeof(*this));
    }
    virtual ~Base()
    {
        cout<<"~Base()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Base::Show()"<<endl;
    }
private:
    int _ma;
};
int main()
{
    Base b(10);
    Base *p = &b;
    p->Show();
    delete p;

    return 0;
}

程式崩潰!  在Base類的建構函式中呼叫clear()函式,將剛構造的物件b清空了。p呼叫show(),非法訪問記憶體,程式崩潰!

看下面一段程式碼段,結果什麼呢?

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int data):_ma(data)  
    {
        cout<<"Base()"<<endl;
        Clear();
    }
    void Clear()
    {
        memset(this, 0 ,sizeof(*this));
    }
    virtual ~Base()
    {
        cout<<"~Base()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Base::Show()"<<endl;
    }
private:
    int _ma;
};

class Derive : public Base
{
public:
    Derive(int data1, int data2):Base(data1),_mb(data2)  
    {
        cout<<"Derive()"<<endl;
    }
    ~Derive()  
    {
        cout<<"~Derive()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Derive::Show()"<<endl;
    }
private:
    int _mb;
};

int main()
{
    Base *p = new Derive(10,10);

    p->Show();
    delete p;

    return 0;
}

物件d中,基類Base的記憶體都被清空了,但是在Derive的建構函式中,又將虛表的地址寫在虛表指標的記憶體裡,故可以訪問Show()函式。

4.————————————————————————-

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int data):_ma(data)  
    {
        cout<<"Base()"<<endl;
        Show();
    }

    virtual ~Base()
    {
        cout<<"~Base()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Base::Show()"<<endl;
    }
private:
    int _ma;
};

class Derive : public Base
{
public:
    Derive(int data1, int data2):Base(data1),_mb(data2)  
    {
        cout<<"Derive()"<<endl;
        Show();
    }
    ~Derive()  
    {
        cout<<"~Derive()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Derive::Show()"<<endl;
    }
private:
    int _mb;
};

int main()
{
    Derive d(10,10);

    return 0;
}

在建構函式裡呼叫虛擬函式,都是靜態繫結。Base類建構函式呼叫Base::Show();Derive類建構函式呼叫Derive::Show()

5.———————————————————————-

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int data):_ma(data)  
    {
        cout<<"Base()"<<endl;
    }
    virtual ~Base()
    {
        cout<<"~Base()"<<endl;
    }
    void Show()
    {
        cout<<"Base::Show()"<<endl;
    }
private:
    int _ma;
};

class Derive : public Base
{
public:
    Derive(int data1, int data2):Base(data1),_mb(data2)  
    {
        cout<<"Derive()"<<endl;
    }
    ~Derive()  
    {
        cout<<"~Derive()"<<endl;
    }
    virtual void Show()
    {
        cout<<"Derive::Show()"<<endl;
    }
private:
    int _mb;
};

int main()
{
    Base *p = new Derive(10,10);
    p->Show();
    delete p;

    return 0;
}

Base類的Show函式不是虛擬函式,Derive類的Show函式是虛擬函式。p->Show();採用靜態繫結,在編譯時已經確定呼叫的是Base類的Show函式。