日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于C语言中继承和多态的实现

發布時間:2023/12/18 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于C语言中继承和多态的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以下的內容綜合了多篇文章,加上一點自己的理解而成。目的為了給自己閱讀他們文章后做一個筆記。在末尾給出了這些文章的地址。

??? 多態的實現可以采用以下幾種方式:
??? (1)使用 vod * (萬能指針)來實現“編譯時多態”。
??? (2)使用函數指針來實現“運行時多態”。
??? (3)使用型如struct struct_name{

????????????? ...............................
????????????? char temp[0]; //或者char *temp;
????????? };
這種形式。

對于(1)舉例如下:

void HandleMsg(unsinged int id, void *p)
{
??? Msg1 *p1;
??? Msg2 *p2;

??? switch(id)
??? {
??? case key1:
??????? p1 = (Msg1*)p;
??????? //do something
??????? break;
??? case key2:
??????? p2 = (Msg2*)p;
??????? //do something
??????? break;
??? default:
??????? break;
??? }
}

??? 這個例子也許不能說明函數的編譯時多態,因為沒有使用函數指針與vod * 之間轉換來轉換去。沒有舉這類例子,是因為想避免這種用法。
??? 對于(2)舉例如下:
#ifndef C_Class
?????? #define C_Class struct
#endif

C_Class A {

?????? C_Class A *A_this;
?????? void (*Foo)(C_Class A *A_this);
?????? int a;

?????? int b;

};

C_Class B{?????????????? //B繼承了A

?????? C_Class B *B_this;? //順序很重要
?????? void (*Foo)(C_Class B *Bthis); //虛函數
?????? int a;
?????? int b;
?????? int c;
};?

void B_F2(C_Class B *Bthis)
{
?????? printf("It is B_Fun/n");
}

void A_Foo(C_Class A *Athis)
{

?????? printf("It is A.a=%d/n",Athis->a);//或者這里
}

void B_Foo(C_Class B *Bthis)
{
??? printf("It is B.c=%d/n",Bthis->c);
}

void A_Creat(struct A* p)
{
?? p->Foo=A_Foo;
?? p->a=1;
?? p->b=2;
?? p->A_this=p;
}?

void B_Creat(struct B* p)
{
?? p->Foo=B_Foo;
?? p->a=11;
?? p->b=12;???
?? p->c=13;
?? p->B_this=p;

}

int main(int argc, char* argv[])
{

?????? C_Class A *ma,a;
?????? C_Class B *mb,b;

?????? A_Creat(&a);//實例化
?????? B_Creat(&b);

?????? mb=&b;
?????? ma=&a;

?????? ma=(C_Class A*)mb;//引入多態指針

?????? printf("%d/n",ma->a);//可惜的就是 函數變量沒有private

?????? ma->Foo(ma);//多態
?????? a.Foo(&a);//不是多態了
?????? B_F2(&b);//成員函數,因為效率問題不使用函數指針
?????? return 0;
}


??? 在C中實現繼承。
??? 對于例(1)中,有個重大的缺點,那就是缺乏類型安全。那么下面就可以使用繼承來實現保證類型安全。

typedef struct tagT_MsgHeader {
??? int id;
??? //...
}MsgHeader;

typedef struct tagT_Msg1 {
??? MsgHeader?????????? h;
??? int???????????????? a;
??? int???????????????? b;
}Msg1;

typedef struct tagT_Msg2 {
??? MsgHeader h;
??? int?????? c;
??? int?????? d;
}Msg2;

然后再重新定義消息處理函數:

void HandleMsg(MsgHeader *ph)
{
??? Msg1 *p1;
??? Msg2 *p2;

??? switch(ph->id)
??? {
??? case key1:
??????? p1 = (Msg1*)(ph);
??????? //do something
??????? break;
??? case key2:
??????? p2 = (Msg2*)ph;
??????? //do something
??????? break;
??? default:
??????? break;
??? }
}

通過繼承保證了類型安全,但是為了保證繼承后的結構體靈活性,繼承的變量MsgHeader h不能作為第一個成員變量,那么p1 =

(Msg1*)(ph)這種強制轉換就無法得到正確的p1的地址,不過通過定義一個宏來實現這個:

#define CONTAINING_RECORD(address, type, field) ((type *)( /
????????????????????????????????????????????????? (PCHAR)(address) - /
????????????????????????????????????????????????? (UINT_PTR)(&((type *)0)->field)))
??? 這個類似的宏定義在linux中最常見。這樣傳入的MsgHeader 的指針經過宏處理,無論MsgHeader h在結構體的那個位置,均能獲得繼承后的結構體的首地址,這樣再來強制轉換就沒有問題了。

順便解釋一下這個宏:
??? #define CONTAINING_RECORD(address, type, field) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

??? 先看&((type *)0)->field,它把“0”強制轉化為指針類型,則該指針指向“0”(數據段基址)。因為指針是“type *”型的,所以可取到以“0”為基地址的一個type型變量field域的地址,這個地址也就等于field域到結構體基地址的偏移字節數。當前地址減去偏移地址便得出該結構體的地址。轉換為(type *)型的指針。


??? 在c中實現純虛類,可以通過在結構體使用函數指針成員來實現。

//------------------結構體中的函數指針類似于聲明子類中必須實現的虛函數-------------
typedef struct
?{
? void? (*Foo1)();
? char? (*Foo2)();
? char*? (*Foo3)(char* st);
?}MyVirtualInterface;
//---------------------------------------------------------------------------------

//------------------類似于純虛類的定義---------------------------------------------
?MyVirtualInterface* m_pInterface;
?
?DoMyAct_SetInterface(MyVirtualInterface* pInterface)
?{
? m_pInterface= pInterface;
?}

?void oMyAct_Do()
?{
? if(m_pInterface == NULL) return;
? m_pInterface->Foo1();
? c = m_pInterface->Foo2();
?}
//---------------------------------------------------------------------------------

//--------------------------子類一-------------------------------------------------
MyVirtualInterface? st[MAX];

//接著定義一些需要實現的函數 Act1_Foo1,Act1_Foo2,Act1_Foo3

MyVirtualInterface* Act1_CreatInterface()
{
?index = FindValid() //對象池或者使用Malloc!應該留在外面申請,實例化
?if(index == -1) return NULL;
?st[index].Foo1 = Act1_Foo1; // Act1_Foo1要在下面具體實現
?st[index].Foo2 = Act1_Foo2;
?st[index].Foo3 = Act1_Foo3;
?Return &st[index];
}
//-----------------------------------------------------------------------------------

//--------------------------主函數---------------------------------------------------
if((p = Act1_CreatInterface()) != NULL)
{
?List_AddObject(&List, p); //Add All
?While(p = List_GetObject())
?{
??DoMyAct_SetInterface(p);//使用Interface代替了原來大篇幅的Switch Case
??DoMyAct_Do();//不要理會具體的什么樣的動作,just do it
??? }
}
//-----------------------------------------------------------------------------------

如果父類不為純虛類的類,那么在子類中通過宏來實現虛函數

MyVirtualInterface* ActByOther1_CreatInterface()
{
?index = FindValid() //對象池或者使用Malloc
?if(index == -1) return NULL;
?St[index].Foo1 = ActByOther1_Foo1; // Act1_Foo1要在下面具體實現
?St[index].Foo2 = ActByOther1_Foo2; //父類中已經實現了的
?St[index].Foo3 = ActByOther1_Foo3; //父類中已經實現了的
?Return &st [index];
}

#define ActByOther1_Foo1 Act1_Foo1? //這就是繼承
ActByOther1_DoByOther() {}?? //當然就可以添加新的實現

引用:

[1]http://blog.csdn.net/baoxingbo/articles/56406.aspx

[2]http://hi.baidu.com/blue_never_died/blog/item/b05f242d389bb734349bf7dd.html

總結

以上是生活随笔為你收集整理的关于C语言中继承和多态的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。