BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #29749同步于 2009/10/11
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

用C语言如何模拟面向对象的三个特性?

never115
2009/10/11镜像同步7 回复
就是如何模拟封装、继承和多态,某次面试问我的,没答出来,网上讨论的也不少,想听听大牛们的解释~~~~
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
Xer机器人#1 · 2009/10/11
封装用结构体 继承把基类(结构体)作为派生类(结构体)的第一个成员,然后用指针强制转换 多态,函数指针吧 就想到这些 【 在 never115 (竹马) 的大作中提到: 】 : 就是如何模拟封装、继承和多态,某次面试问我的,没答出来,网上讨论的也不少,想听听大牛们的解释~~~~
FadeToBlack机器人#2 · 2009/10/11
随便写个类逆向一下你就知道,很简单的原理 【 在 never115 (竹马) 的大作中提到: 】 : 就是如何模拟封装、继承和多态,某次面试问我的,没答出来,网上讨论的也不少,想听听大牛们的解释~~~~
jmpesp机器人#3 · 2009/10/11
【 在 FadeToBlack 的大作中提到: 】 : 随便写个类逆向一下你就知道,很简单的原理 多态的实现: mov eax, 【ecx】 call dword ptr 【eax+虚函数偏移】
never115机器人#4 · 2009/10/11
说得都好简单啊。。。 Child c; Base* pb=(Base*)&c; pb->print(); 要让print是不同的行为,要建个类似虚表的东西吗?
jmpesp机器人#5 · 2009/10/11
【 在 never115 的大作中提到: 】 : 说得都好简单啊。。。 : Child c; : Base* pb=(Base*)&c; : ................... 不用什么虚表的,直接在结构内用函数指针变量就行了,然后在适当的时候修改就产生多态了
wks机器人#6 · 2009/10/11
typedef struct { // Instance void *klass; // "Class" of the instance int x; } Base; typedef struct { // Class (Class is virtual-methods table) void (*foo)(); } BaseClass; typedef struct { Base parent; // Derived derives Base int y; } Derived; typedef struct { BaseClass parent_class; } DerivedClass; void foo_base() { printf("hello from base\n"); } void foo_derived() { // overrides foo_base() printf("hello from derived\n"); } BaseClass bc; bc.foo=foo_base; DerivedClass dc; dc.foo=foo_derived; Base* base_new() { // Constructor Base *b = malloc(sizeof(Base)); b->klass=&bc; return b; } Derived* derived_new() { // Constructor Derived *d = malloc(sizeof(Derived)); ((Base*)d)->klass = &dc; return d; } // Create two instances. Base *b = base_new(); Derived *d = derived_new(); // Access member variables b->x = 42; ((Base*)d)->x = 43; // Inherited member d->y = 65; void base_print_member_x(Base* b) { // Method of Base printf("%d\n",b->x); } base_print_member_x(b); // outouts 42 // polymorphism: It is the show time!!!!!!!!! Base instances[2] = {b,d}; for(int i=0;i<2;i++) { Base* inst = instances[i]; // We consider both b and d as "Base", even though d is "Derived" BaseClass* klass = inst->klass; // Remember that klass->foo is overwritten in Derived. klass->foo(); } 总结: - C语言没有类,实例用结构体表示。 - 继承的时候,子类的结构体中第一个成员是父类,这样子类结构指针只要强制转换成父类结构指针,就能当父类用。 - “方法”就是第一个元素是实例指针的普通函数。 - 虚函数存在另一个“类结构”中,每个类只有一个,独立于实例存在,里面存虚函数的指针 - 子类的虚函数覆盖父类,就是在子类的类结构中,把相应的虚函数指针赋成不同的函数。 详情请看GLib的GObject
wks机器人#7 · 2009/10/11
封装不太好做。可以在实例结构里放一个指向私有成员的指针,但这个私有成员的定义在.c文件里,不能被include,所以外部的用户无法知道。 // priv.h: typedef struct _MyPrivate MyPrivate; // We don't have struct MyPrivate in this file. typedef struct _MyInstance MyInstance; struct _MyInstance { MyPrivate *priv; }; MyInstance* my_instance_new(); // priv.c #include "priv.h" struct _MyPrivate { int x; // A private member }; MyInstance* my_instance_new() { MyInstance* self = malloc(sizeof(MyInstance)); self->priv = malloc(sizeof(MyPrivate)); return self; }