网站图标怎么下载,企业网站建设方案 功能规划,松江网站开发培训学校,网络架构方法以下的内容综合了多篇文章#xff0c;加上一点自己的理解而成。目的为了给自己阅读他们文章后做一个笔记。在末尾给出了这些文章的地址。 多态的实现可以采用以下几种方式#xff1a; (1)使用 vod * (万能指针)来实现“编译时多态”。 (2)使用函数指针来实现“运行时…以下的内容综合了多篇文章加上一点自己的理解而成。目的为了给自己阅读他们文章后做一个笔记。在末尾给出了这些文章的地址。 多态的实现可以采用以下几种方式 (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-FooA_Foo; p-a1; p-b2; p-A_thisp; }
void B_Creat(struct B* p) { p-FooB_Foo; p-a11; p-b12; p-c13; p-B_thisp;
}
int main(int argc, char* argv[]) { C_Class A *ma,a; C_Class B *mb,b; A_Creat(a);//实例化 B_Creat(b); mbb; maa; 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_Foo1Act1_Foo2Act1_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