سؤال

ما هي أفضل طريقة لإنشاء مفردة في لغة C؟سيكون الحل المتزامن أمرًا رائعًا.

أدرك أن لغة C ليست اللغة الأولى التي ستستخدمها للغة المفردة.

هل كانت مفيدة؟

المحلول

أولا، C ليست مناسبة للبرمجة OO. تريد ان تكون القتال على طول الطريق اذا كنت تفعل. ثانيا، سنغلتونس متغيرات فقط ثابتة مع بعض التغليف. بحيث يمكنك استخدام متغير عمومي ثابت. ومع ذلك، والمتغيرات العالمية وعادة ما يكون عدد كبير جدا من الأمراض المرتبطة بها. هل يمكن خلاف ذلك استخدام دالة متغير ثابت محلي، مثل هذا:

 int *SingletonInt() {
     static int instance = 42;
     return &instance;
 }

وأو ماكرو ذكاء:

#define SINGLETON(t, inst, init) t* Singleton_##t() { \
                 static t inst = init;               \
                 return &inst;                       \
                }

#include <stdio.h>  

/* actual definition */
SINGLETON(float, finst, 4.2);

int main() {
    printf("%f\n", *(Singleton_float()));
    return 0;
}

وأخيرا، تذكر أن سنغلتونس معظمهم يتعرضون لسوء المعاملة. ومن الصعب الحصول عليها الحق، وخصوصا في ظل بيئات متعددة الخيوط ...

نصائح أخرى

وأنت لست بحاجة إليها. C بالفعل المتغيرات العالمية، لذلك لا تحتاج إلى العمل في جميع أنحاء لمحاكاة لهم.

وانها نفس النسخة C ++ حد كبير. يكون مجرد وظيفة يقوم بإرجاع مؤشر المثال. ويمكن أن يكون متغير ثابت داخل الدالة. التفاف الجسم وظيفة مع مقطع حرج أو مزامنة pthread، اعتمادا على منصة.

#include <stdlib.h>

struct A
{
    int a;
    int b;
};

struct A* getObject()
{
    static struct A *instance = NULL;

    // do lock here
    if(instance == NULL)
    {
        instance = malloc(sizeof(*instance));
        instance->a = 1;
        instance->b = 2;
    }
    // do unlock

    return instance;
};

ملحوظة ان كنت بحاجة الى وظيفة لتحرير المفرد أيضا. لا سيما إذا كان الاستيلاء على أي موارد النظام التي لا تصدر تلقائيا عند الخروج العملية.

وتحرير: جوابي يفترض المفرد تقوم بإنشاء معقد إلى حد ما، ولها عملية إنشاء متعددة الخطوات. إذا كانت بيانات ثابتة فقط، والذهاب مع عالمي مثل الآخرين قد اقترح.

وA المفرد في C سيكون غريب جدا. . . أنا لم أر قط مثال على "وجوه المنحى C"، التي بدت أنيقة للغاية. إذا كان ذلك ممكنا، والنظر في استخدام C ++. C ++ يسمح لك لانتقاء واختيار الميزات التي تريد استخدامها، وكثير من الناس مجرد استخدامه ك "أفضل C".

وفيما يلي نمط نموذجي جدا لقفل خالية من مرة واحدة التهيئة. وInterlockCompareExchangePtr مقايضة بالذرة في قيمة جديدة إذا السابق لاغيا. هذا يحمي إذا مواضيع متعددة في محاولة لخلق المفرد في نفس الوقت، واحد فقط سيفوز. الآخرين سيتم حذف من كائن تم إنشاؤه حديثا.

MyObj* g_singleton; // MyObj is some struct.

MyObj* GetMyObj()
{
    MyObj* singleton;
    if (g_singleton == NULL)
    {
        singleton = CreateNewObj();

        // Only swap if the existing value is null.  If not on Windows,
        // use whatever compare and swap your platform provides.
        if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL)
        {
              DeleteObj(singleton);
        }
    }

    return g_singleton;
}

DoSomethingWithSingleton(GetMyObj());

وهنا وجهة نظر أخرى:كل ملف في برنامج C هو فعليًا فئة مفردة يتم إنشاء مثيل لها تلقائيًا في وقت التشغيل ولا يمكن تصنيفها ضمن فئة فرعية.

  • المتغيرات الثابتة العامة هي أعضاء صفك الخاص.
  • العالمية غير الثابتة عامة (فقط أعلن عنها باستخدام extern في بعض الملفات الرأسية).
  • الوظائف الثابتة هي طرق خاصة
  • الوظائف غير الثابتة هي الوظائف العامة.

أعط كل شيء بادئة مناسبة والآن يمكنك استخدامها my_singleton_method() بدلا من my_singleton.method().

إذا كان المفرد الخاص بك معقدًا، فيمكنك كتابة ملف generate_singleton() لتهيئتها قبل الاستخدام، ولكن بعد ذلك تحتاج إلى التأكد من أن جميع الطرق العامة الأخرى تتحقق مما إذا تم استدعاؤها وخطأ إذا لم يتم استدعاؤها.

وفقط تفعل

void * getSingleTon() {
    static Class object = (Class *)malloc( sizeof( Class ) );
    return &object;
}

والذي يعمل في بيئة متزامنة أيضا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top