C++總結6——繼承與多型的筆試題【轉】
阿新 • • 發佈:2018-12-17
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函式。