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;
}
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函數。
這里寫圖片描述


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: