c 有關編譯期和執行期的訪問

2021-06-18 14:58:20 字數 2137 閱讀 4831

#include using namespace std;  

class a

出現了很有趣的結果,在main函式中,訪問到了b類中的私有方法。為什麼會出現這樣的結果呢?

一般來說外部物件訪問類的私有成員,除非是友元,否則在編譯的時候就會報錯,但是上面那段**卻可以正常的編譯通過。

c++因為支援物件導向程式設計,制訂了一系列實現策略的語言機制。其中,各種各樣的「限制」主要是出現在編譯時:因此如果直接b  d; d.f();   就會導致編譯錯誤:編譯器發現   b::f()是b類的私有成員函式,因此拒絕這樣的訪問。

這裡我們可以區分類和物件:類是編譯期的概念,也是「訪問許可權」、「成員資料」、「成員函式」這幾個概念的「作用域」。而物件的作用域是執行期。它包括類的例項、引用和指標。   

a   *pa   =   new   b();   

這裡   pa   是乙個   a* , 所以就作為乙個a類的指標參與了編譯;因此從pa呼叫f()在編譯器眼中,就是呼叫了a類的公開成員函式f()因此通過編譯;然後在執行時,由於多型作用pa呼叫的f()是派生類的f()成員函式。雖然這時f()是private成員函式,但是由於   private/public   這些訪問控制是編譯時的限制,在執行時無效,所以b::f() 被成功呼叫。如果能夠理解這兩個在不同時間作用的概念,這個問題就很好理解.

由這個問題,就引出了編譯期和執行期的概念。

顧名思義,編譯期指的是編譯器在編譯**的時候,而執行期指的是程式執行的時候。

以上為引用,為什麼要看這段話呢,是讀

c++物件模型的時候遇到下面的問題; 定義

point3dorigin,*pt = &origin. 關於

origin.x= 0.0

與 pt->x= 0.0

的區別,深度探索

c++模型中的一段話:

"當point3d

是乙個derived class,

而在其繼承結構中有乙個

virtual base class,

並且被訪問的

member(

如本例的

x)是乙個從該

virtual base class 

繼承而來的

member時,

就會有重大的差異

".這時候我們 不能夠說

pt必然指向哪一種

classtype(

因此我們也就不知道編譯時期這個

member

真正的offset位置)

所以這個訪問操作必須延遲至執行器

,,經由乙個而外的間接導引

,才能夠解決

.但如果使用

origin,

就不會有這些問題

,其型別無疑是

point3d class,

而即使它繼承自

virtual baseclass,members

的 offset

位置也在編譯器就固定了

.乙個好的編譯器甚至可以靜態的經由

origin

就解決掉對

x的訪問.

這段話還是要從菱形繼承的角度理解,

b,c虛繼承a,

d虛繼承b,

c。那麼

b型別的指標指向類物件和指向

d類物件的時候,

a中的資料的

offset

是不一樣的。不言而喻,不然就不要偏移表了。

要強調的是,這裡一定要注意必須有虛繼承這個環節。否則如果

b,c並不是虛繼承

a的話,那麼在

d中雖然存在兩個

a類物件,但是當指標的型別確定的時候,

a中資料的偏移量也是確定的。

正因為編譯期搞定的是指標的型別,從而決定了允許他訪問的函式,變數,如果不存在虛繼承,那麼每乙個型別中的資料的

offset

當然是確定的,但是虛繼承卻使得子類不在獨有乙個基類的物件,那麼他的便宜當然是無法確定的,這要根據它指向的真正的物件的型別的資料排布而決定,所以必須推遲到執行期。

由於編譯期只是單純根據定義變數型別來決定可訪問範圍,這就給了指向父類物件的子類指標訪問了不屬於父類的函式和在虛繼承機制下,利用父類的

publicaccess

來訪問子類的

private

函式空間。

編譯期與執行期

編譯期確切地說應該是得到obj檔案的過程,得到最後可執行檔案的過程叫鏈結 編譯期最前,最後的是執行期。編譯期錯誤是編譯期間就能被編譯器捕捉到的錯誤,譬如定義乙個過大陣列,不過最常見的還是語法錯誤或者拼寫錯誤。執行期錯誤可以也可以是分配乙個過大的陣列,不過在c 裡面這個可以因為new或者malloc產...

C 的執行期多型和編譯期多型

今日的c 不再是個單純的 帶類的c 語言,它已經發展成為乙個多種次語言所組成的語言集合,其中泛型程式設計與基於它的stl是c 發展中最為出彩的那部分。在物件導向c 程式設計中,多型是oo三大特性之一,這種多型稱為執行期多型,也稱為動態多型 在泛型程式設計中,多型基於template 模板 的具現化與...

編譯期多型和執行期多型

所謂的多型是通過乙個單一的識別符號支援不同的特定行為的能力。靜態多型 編譯期多型 動態多型 執行期多型 虛函式過載 模板 轉換 型別別名 今天我們就只討論從繫結時間來分的多型種類,即編譯期多型和執行期多型。執行期多型可以說只要學了c 的人都是知道的。因為執行期多型就是我通俗所說的多型,它的提出可以歸...