INTERFACE C# LÀ GÌ

  -  
Straight of the bat I understand that ANSI C is not an object orientated programming language. I want to learn how lớn apply a particular oo technique using c.

Bạn đang xem: Interface c# là gì

For example, I want lớn create several audio effect classes that all have the same function names but different implementations of those functions.

If I was making this in a higher màn chơi language I would first write an interface & then implement it.

AudioEffectInterface-(float) processEffect DelayClass-(float) processEffect // vày delay code return resultFlangerClass-(float) processEffect // vì flanger code return result-(void) main effect= new DelayEffect() effect.process() effect = new FlangerEffect() effect.process()How can I achieve such flexibility using C?


giới thiệu
Improve this question
Follow
asked Jun 10, 2011 at 9:59
*

dubbeatdubbeat
7,6371818 gold badges6767 silver badges117117 bronze badges
1
địa chỉ a bình luận |

3 Answers 3


Sorted by: Reset to default
Highest score (default) Trending (recent votes count more) Date modified (newest first) Date created (oldest first)
54
There are three distinct ways you can achieve polymorphism in C:

Code it outIn the base class functions, just switch on a class type ID to gọi the specialized versions. An incomplete code example:

typedef enum classType CLASS_A, CLASS_B classType;typedef struct base classType type; base;typedef struct A base super; ... A;typedef struct B base super; ... B;void A_construct(A* me) base_construct(&me->super); super->type = CLASS_A;int base_foo(base* me) switch(me->type) case CLASS_A: return A_foo(me); case CLASS_B: return B_foo(me); default: assert(0), abort(); Of course, this is tedious to vì for large classes.

Xem thêm: Trò Chơi Đại Ca Ra Tù 8 Mới Nhất 2022, Dai Ca Ra Tu 8

Store function pointers in the objectYou can avoid the switch statements by using a function pointer for each thành viên function. Again, this is incomplete code:

typedef struct base int (*foo)(base* me); base;//class definitions for A and B as aboveint A_foo(base* me);void A_construct(A* me) base_construct(&me->super); me->super.foo = A_foo;Now, calling code may just do

base* anObject = ...;(*anObject->foo)(anObject);Alternatively, you may use a preprocessor macro along the lines of:

#define base_foo(me) (*me->foo)(me)Note that this evaluates the expression me twice, so this is really a bad idea. This may be fixed, but that"s beyond the scope of this answer.

Xem thêm: Hướng Dẫn Kết Nối Tay Cầm Ps4 Với Pc Win 10 Đơn Giản Nhất, Hướng Dẫn Kết Nối Tay Cầm Ps4 Với Máy Tính

Use a vtableSince all objects of a class giới thiệu the same phối of member functions, they can all use the same function pointers. This is very close lớn what C++ does under the hood:

typedef struct base_vtable int (*foo)(base* me); ... Base_vtable;typedef struct base base_vtable* vtable; ... Base;typedef struct A_vtable base_vtable super; ... A_vtable;//within A.cint A_foo(base* super);static A_vtable gVtable = .foo = A_foo, ...;void A_construct(A* me) base_construct(&me->super); me->super.vtable = &gVtable;;Again, this allows the user code to vày the dispatch (with one additional indirection):

base* anObject = ...;(*anObject->vtable->foo)(anObject);Which method you should use depends on the task at hand. The switch based approach is easy to whip up for two or three small classes, but is unwieldy for large classes và hierarchies. The second approach scales much better, but has a lot of space overhead due lớn the duplicated function pointers. The vtable approach requires quite a bit of additional structure and introduces even more indirection (which makes the code harder to read), but is certainly the way lớn go for complex class hierarchies.