إستيقظت هذا الصباح على فكرة، لاأعلم مدى جنونها، لكنني أظن أنه بالإمكان إستخدام البرمجة كائنية التوجه في لغة السي.
التحدي يشرح نفسه بنفسه، لذا دعونا نختبر بعض قدرات لغة السي، ونرى الى أي مدى يمكننا أن نصل :D .
إستيقظت هذا الصباح على فكرة، لاأعلم مدى جنونها، لكنني أظن أنه بالإمكان إستخدام البرمجة كائنية التوجه في لغة السي.
التحدي يشرح نفسه بنفسه، لذا دعونا نختبر بعض قدرات لغة السي، ونرى الى أي مدى يمكننا أن نصل :D .
لتوليد الأفكار
#include <stdio.h>
#include <string.h>
void info (int age, char *name)
{
printf("age : %d\nname: %s\n", age, name);
return;
}
typedef struct _Person
{
int age;
char name [32];
void (*pInfo)(int, char *);
}
Person;
int main (void)
{
Person person;
person.age = 24;
strcpy(person.name, "zirek99i");
person.pInfo = info;
person.pInfo(person.age, person.name);
getchar ();
return 0;
}أعتقد أنك تشير إلى استخدام مؤشرات الدوال، مشكلته أنه غير عملي ولايقدم شيء أكثر من استخدام "." أو "->" قبل استدعاء الوظيفة، وهذا لايجعل الكود كائني.
هناك إسلوب متبع في كثير من مكتبات C، أشهر مكتبة تستخدمه gtk ومكتبتها glib، مثل:
/* main.c */
#include "public.h"
#include <stdio.h>
int main(int argc, char **argv) {
/* إنشاء كائن */
Object *obj = object_new(2);
/* عمليات على الكائن */
object_method(obj);
object_set_a(obj, 3);
printf("%d %d\n", object_get_a(obj), object_get_b(obj));
/* إنهاء الكائن */
object_destroy(obj);
return 0;
}/* public.h */ #ifndef __PUBLIC_H__ #define __PUBLIC_H__ typedef struct _Object Object; Object* object_new(int a); void object_method(Object * obj); void object_set_a(Object *obj, int a); int object_get_a(Object *obj); int object_get_b(Object *obj); void object_destroy(Object *obj); #endif
/* private.h */
#ifndef __PRIVATE_H__
#define __PRIVATE_H__
#include "public.h"
/* any private definitions */
struct _Object {
int a;
int b;
};
#endif/* implementation.c */
#include "private.h"
#include <stdio.h>
#include <stdlib.h>
/* وظائف خاصة */
static int _object_pow2(int n) {
return n * n;
}
/* وظائف عامة */
Object* object_new(int a) {
Object *obj;
if( (obj = calloc(1, sizeof(Object))) == NULL ) {
return NULL;
}
/* تهيئة الكائن */
obj->a = a;
obj->b = _object_pow2(a);
return obj;
}
/* وظائف */
void object_method(Object * obj) {
printf("%d:%d\n", obj->a, obj->b);
}
/* setters and getters */
void object_set_a(Object *obj, int a) {
obj->a = a;
obj->b = _object_pow2(a);
}
int object_get_a(Object *obj) {
return obj->a;
}
int object_get_b(Object *obj) {
return obj->b;
}
void object_destroy(Object *obj) {
/* إنهاء الكائن */
if(obj) {
free(obj);
}
}هدفي من التحدي ليس عرض المكتبات، لكني أردت فقط أن يستفيد الأعضاء من الإستخدامات المتقدمة لـ static، extern، والـ Preprocessors وماالفرق بين إستخدامهم داخل نفس الملف ومن ملف آخر، وبما أن الأمر أكبر من أن يتم إحتوائه داخل موضوع عادي، قررت أن أضعه على شكل تحدي. ولم يخطر ببالي أفضل من الـ Oriented object كأساس ;).
اقتباس
هذا الأسلوب لا أعتبره محاكاة لأسلوب الـ OOP, للأسباب التالية :
أعتقد أن جعل لغة C كائنية التوجه يتنافى مع المبادئ التي تعتمد عليها كـ imperative programming language.
تحياتي.
تم تعديل هذه المشاركة بواسطة Snack3r في 30 نوفمبر 2013 في 18:22
C++ and Java, say, are presumably growing faster than plain C, but I bet C will still be around. ― Dennis Ritchie
~OoO~________--------------------------------------------________~OoO~
من مواضيعي :
بالنسبة للنقطة الأولى والثانية التي طرحتها أخي Snack3r فقد قام زكريا بحلها عن طريق مؤشر التابع .. يعني يقوم بتعريف مؤشر للتابع ثم ستستخدمه كتابع عادي ..
أما النقاط الباقية فمعك حق فيها ..
أخي زكريا أنا فهمت فكرتك .. ولكن حتى تشرحها أكثر اكتب برنامج الاختبار للــstruct ويجب علينا بناؤها بما يحقق برنامج الاختبار .. يعني اكتب الـ main ونحن نكتب الباقي :)
المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية
جارٍ التحقق من المتواجدين…