貌似有些同學還不太明白這個,我試著用c**描述c++類相關的一些實現方式。
設類abc,bc繼承於a,都有個虛函式f(),析構函式為虛
c++**
//---------a
struct a{
a(){
void f(){
printf("class a\n";
virtual ~a(){
struct b:public a{
b(){
virtual void f(){
printf("class b\n";
virtual ~b(){
struct c:public a{
c(){
void f(){
printf("class b\n";
virtual ~c(){
main(){
a* p=new a;
p->f();
delte p;
p=new b;
p->f();
delete p;
//c語言描述,語法問題請無視,否則要寫一大堆typedef定義型別
設c_a()為a建構函式 d_a()為a的析構函式,vt_a為a的虛函式表結構
b,c類似
先構造結構
struct vt_a{
destructfun_ptr;
virtual_f_ptr;
這裡b和c的vtable和a結構一致,沒有擴充函式
vt_b{
vt_a father;//
//擴充的其他函式在下面
struct a{
vt_a vtable;
//a的其他成員變數
struct b{
a father_a;
//b的其他成員變數
c和b類似
//生成虛函式表
vt_a vtable_a={
d_a,vf_a_f;
vt_b vtable_b={
d_b,vf_b_f;
vt_c vtable_c={
d_c,vf_c_f;
編譯p=new a;
p->f();
delete p;
編譯為//第一句
p=new_op(sizeof(a));//對應的new函式(全域性,區域性),可以認為就是malloc
a* pa==(a*)p;
pa->vtable=vtable_a; //對不同的子類,vtable指向不同的表
pa->c_a(pa);
//第二句
pa->vtable->virtual_f_ptr(pa);//這裡就是多型的實現方法(vtable的不同,實現呼叫子類的虛函式)
//第3句
pa->vtable->destructfun_ptr(pa);
delete_op(pa);//對應的delete函式,可以認為就是free
///最後是鏈式析構的實現方式
d_a(){
//自定義的**
d_b()
//自定義的**
//編譯器新增
d_a(this);
這就是鏈式析構的原理
編譯時乙個類的父類是一定可以確定的,可以這麼認為,乙個子類的析構函式呼叫後,this就退化為父類的型別了,這時繼續呼叫父類的析構函式(編譯器實現),直到沒有父類為止。
多重繼承時情況和單繼承類似,只是記憶體布局不同,子類和父類指標轉換時可能會有偏移值。
C 類編譯器自動生成函式的實現
在c 中,乙個類有八個預設函式 預設建構函式 預設拷貝建構函式 預設析構函式 預設過載賦值運算子函式 預設過載取址運算子函式 預設過載取址運算子const函式 預設移動建構函式 c 11 預設過載移動賦值操作符函式 c 11 class myclass c 預設建構函式是對類中的引數提供預設值的建構...
編譯器預設實現的類成員函式
以下幾種情況編譯會生成類成員函式情況如下 include include include 編譯器為我們實現了幾個類成員函式?class empty empty e empty b e empty d empty b d empty f b empty operator 取址運算子 const emp...
編譯器實現(六)
語義分析可以分為兩類。第1類是程式的分析,要求根據程式語言的規則建立其正確性,並保證其正確執行。對於不同的語言來說,語言定義所要求的這一類分析的總量變化很大。在lisp和smalltalk這類動態制導的語言中,可能完全沒有靜態語義分析 而在a d a這類語言中就有很強的需求,程式必須提交執行。其他的...