您的位置:首页 > 编程语言 > C语言/C++

GeekBand c++學習筆記之五(對象模型與動態綁定的討論)

2016-06-12 20:35 274 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/ak47skyang/article/details/51648390

對象模型(Object Model):甚麼是對像模型?對象模型就是把原本都是代碼的程序,將其圖形化,把它們各自的關係都表現出來,讓人更好理解,每個對象或是類的關聯性

vptr:英文就是virtual pointer,就是虛擬指針的意思,跟指針有相似的特徵,比如說:他的內存占用也是4byte,而它的功用是把每個類的對象所擁有的虛函數,用一個指針指出,而且不管多少的虛函數,都只有一個虛擬指針,這樣好處,我們會再下面再討論

vtbl:英文就是virtual table,就是虛擬表格的意思,這個其實就是存放虛函數的地方,而他也是與virtual pointer共同存在的,因為virtual pointer就是將指針指向他

先給出一個例子,這個例子出自於老師的課件:

創造出三個類,分別是A,B,C,這三個類,這三者的關係是繼承,B繼承A,C繼承B,代碼如下:

<span style="font-size:18px;"><span style="font-size:18px;">class A
{
public:
virtual void vfuncl();
virtual void vfunc2();
void func1();
void func2();
private:
int m_data1,m_data2;
};
class B:public A
{
public:
virtual void vfunc1();
void func3();
private:
int m_data3;
};
class C: public B
{
public:
virtual void vfunc1();
void func4();
private:
int m_data1;
int m_data2;
}
</span>

關係圖示:


我們現在就可以知道這三個類之間的關係,然後我們再把他的內存情況畫出



我們可以看出整個內存與虛函數的情況在繼承關係下是怎麼樣的!而了解了對象模型,vptr和vtbl之後,我們就可以開始學習動態綁定,同時比較靜態綁定,同時我們必須先知道,繼承數據是內存的繼承,而繼承內存是調用權的繼承,跟內存無關,只是權力的繼承

我們先假設

<span style="font-size:18px;">C* p=&c;</span>
設p是指向C的指針,我們通過p調用c::vunc1() 靜態綁定:

這是在C語言所用的方法,他會再編譯器中利用call,找到地址,調用函數,由於本篇的重點在動態綁定,所以此方法著墨較少

動態綁定:

這是在C++中所用的方法,我們先看他的代碼表達式:

<span style="font-size:18px;">(*p->vptr
)(p)</span>
我們就來走一遍思路,首先通過p要調用c::vunc1(),因為p是指向c的,而func1()是虛函數,所以我們可以想出
<span style="font-size:18px;">p->vptr
</span>
因為要調用c::vunc1(),就先把p指向vptr,再讓vptr指向vtbl,就可以想到
<span style="font-size:18px;">p->vptr
</span>
這裡的n就是在vtbl這個表格中,想像他是數組,而n就是他所存放的位置
<span style="font-size:18px;">(*p->vptr
)(p)</span>
就是編譯器在動態綁定時,所做的反應,同時動態綁定是由編譯器所決定的 最後我們在總結一下,動態綁定的優缺點以及他的條件:

優點:

1.其是通過虛函數實現的,而虛函數是通過一張表格(virtual table)實現的。這個表中記錄了虛函數的位址,解決繼承、覆蓋的問題,保證使用時能夠根據物件的實際類型調用正確的函數

2.因為期的所有傳遞都是以指針的方式解決,效率高

缺點:

1.動態繫結在函式呼叫時需要在虛函數表中查找,所以性能比靜態函式呼叫稍低

2.通过父类类型的指针访问子类自己的虚函数将发生错误

條件:

1.必須通過指針調用,如:C* p=&c;

2.這個指針必須向上轉型(up-cast),也就是要子類的指針訪問父類的虛函數

3.調用的必須是虛函數













内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: