هل يمكنني تنفيذ نمط أسلوب المصنع في C++ دون استخدام جديد؟

StackOverflow https://stackoverflow.com/questions/1031301

سؤال

أنا أعمل في بيئة مضمنة (Arduino/AVR ATMega328) وأريد تنفيذ نمط أسلوب المصنع في لغة C++.ومع ذلك، فإن المترجم الذي أستخدمه (avr-gcc) لا يدعم new الكلمة الرئيسية.هل هناك طريقة لتنفيذ هذا النمط دون استخدام new?

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

المحلول

ومنذ يستند المترجم AVR على مترجم دول مجلس التعاون الخليجي، فمن المحتمل جدا لدعم الكلمة الجديدة. ما هو بالضبط الخطأ الذي تحصل عليه. انا التخمين انها خطأ ارتباط / مترجم على غرار وظيفة غير محددة، وهي المشغل الجديد. هناك فرق بين المشغل الجديد والمشغل الجديد، يتم استخدام أول من خلق الأشياء ويستخدم هذا الأخير إلى تخصيص الذاكرة للكائنات. المشغل الجديد يدعو المشغل الجديد لنوع الكائن الذي يتم إنشاؤه، ثم initialises v- الجدول الكائن ويدعو منشئات الكائن. تقول قراءة هذه التعليمات أن المشغل الجديد لم يتم تعريف في المكتبات القياسية. هذا أمر سهل لإصلاح، ومجرد تعريف واحد:

void *operator new (size_t size)
{
  return some allocated memory big enough to hold size bytes
}

ووستحتاج إلى تحديد حذف أيضا:

void operator delete (void *memory)
{
   free the memory
}

والشيء الوحيد الذي لإضافة هو إدارة الذاكرة، وتخصيص وتحرير كتل الذاكرة. ويمكن القيام بذلك بشكل مسلي، والحرص على عدم هزم أي ذاكرة الحالية المخصصة (الرمز، / بيانات عالمية ثابتة، المكدس). يجب أن يكون اثنين من الرموز المعرفة - واحدة لبدء تحرير الذاكرة واحد لنهاية الذاكرة. يمكنك تخصيص حيوي وتحرير أي جزء من الذاكرة في هذه المنطقة. سوف تحتاج إلى إدارة هذه الذاكرة نفسك.

نصائح أخرى

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

ووصورة كبيرة لأسلوب مصنع لإنشاء كائن، وهو ما يعني استهلاك الذاكرة الكومة. على نظام مضمن، مقيدة بك من ذاكرة الوصول العشوائي، والحاجة إلى اتخاذ جميع القرارات التصميم الخاص بك مع حدود الذاكرة الخاصة بك في الاعتبار. وATmega328 ديه 2 KB RAM فقط. أوصي بعدم استخدام الذاكرة المخصصة حيوي في هذه المساحة الضيقة.

ودون معرفة مشكلتك في مزيد من التفاصيل، أود أن أوصي معلنا بشكل ثابت حفنة من مثيلات الفئة وإعادة استخدام تلك الحالات في بعض الأزياء. هذا يعني أنك بحاجة إلى معرفة متى ولماذا يتم إنشاء الأشياء الخاصة بك و- بنفس القدر من الأهمية - متى ولماذا ينتهي. فأنت بحاجة إلى معرفة كم تحتاج إلى أن يكون نشطا في وقت واحد وكم من الممكن أن يكون نشطا في وقت واحد.

و!! عميد

وماذا عن شيء مثل هذا؟

MyClass *objp = (MyClass*)malloc(sizeof(MyClass));
*objp = MyClass();  // or any other c'tor

وتحرير: نسيت أن أذكر، فإنه يفترض MyClass لديه عامل التعيين

وEDIT2: شيء آخر لقد نسيت - نعم، هناك مسكتك (انها C ++، هناك دائما gotchas). سيكون لديك لاستدعاء دي تور يدويا للكائن، لأنك لا تستطيع استخدام المجاني.

إذا كنت تستخدم مصنع يعني أنك تريد بعض السلوك الديناميكي ملزم مما يدل على أن لديك بعض الدالات الظاهرية. على الرغم من أنه قد يكون من الممكن تخصيص الذاكرة لmalloc الكائن باستخدام () سوف vtable الطبقة لا يكون الإعداد بشكل صحيح، وبالتالي الدعوة إلى وظائف افتراضية سوف تعطل. أنا لا أرى أي طريقة للقيام بذلك عندما دينامية ملزم هو مطلوب.

هل يمكنك أن تفعل مالوك؟إذا كان الأمر كذلك، يمكنك ضبط الكائن الخاص بك بهذه الطريقة.

وما هي أيضًا طبيعة الأشياء التي ترغب في إنشائها من المصنع؟

  • هل هم غير قابلين للتغيير؟
  • هل يهدف المصنع فقط إلى إنتاج مجموعة محدودة من الكائنات التي يمكن معرفتها في وقت الترجمة؟

إذا كانت الإجابة بنعم على كلا السؤالين، فيمكنك تخصيص الذاكرة بشكل ثابت لمجموعة الكائنات غير القابلة للتغيير والسماح لأسلوب المصنع بإرجاع المؤشرات إلى الكائن المناسب.

لن ينجح هذا إذا كانت الإجابة لا على أي من السؤالين.أيضًا مع هذا النهج لديك مشكلة تخصيص تلك الذاكرة دائمًا.

وكانت هناك طريقة لقد حلت هذه المشكلة في نظام مضمن مع معايير الترميز صارمة (حيث لم يسمح لنا لاستخدام "جديد" أو "حذف") لإنشاء مجموعة ثابتة من الكائن المطلوب. ومن ثم استخدام مؤشرات ثابتة على كائنات المخصصة بالفعل، وتخزين هذه القيم عاد (باستخدام المتغيرات ثابتة و / أو المتغيرات عضو) لتنفيذ أحدث من الكائنات المختلفة.

// Class File ---------------------------------------------------
class MyObject {
    public:
        MyObject* getObject();

    private:
        const int MAX_POSSIBLE_COUNT_OF_OBJECTS = 10;
        static MyObject allocatedObjects[MAX_POSSIBLE_COUNT_OF_OBJECTS];

        static allocatedObjectIndex = 0;
};

// Implementation File ------------------------------------------

// Instantiate a static array of your objects.
static MyObject::allocatedObject[MAX_POSSIBLE_COUNT_OF_OBJECTS];

// Your method to return already created objects.
MyObject* MyObject::getObject() {

    if (allocatedObjectIndex < (MAX_POSSIBLE_COUNT_OF_OBJECTS - 1)) {
        return allocatedObjects[allocatedObjectIndex++];
    } else {
        // Log error if possible
        return NULL;
    }
}

يرجى أن يكون على علم مسبق. هذا كله من ذاكرتي وأنا لم أكتب أي C ++ في أكثر من 8 أشهر.

وأيضا ملاحظة: هذا له عيب خطير في أن تقوم بتخصيص مجموعة من ذاكرة الوصول العشوائي في وقت الترجمة

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