C++總結6——繼承與多型的筆試題
阿新 • • 發佈:2019-01-30
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;
}
pr`
vate:
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函式。