سؤال

ورأيت فئة وهي فئة الذي يعرف مثل هذا ..

class StringChild : public StringBase
    {
public:
    //some non-virtual functions
    static StringChild* CreateMe(int size);
private:
    unsigned char iBuf[1];
    };

وظيفة ثابتة مصنع لديها تنفيذ التالية ..

return new(malloc(__builtin_offsetof(StringChild ,iBuf[size]))) StringChild();

وهكذا بقدر ما أفهم هذه الوظيفة يستخدم وضع جديد لتوسيع هذه الفئة.

هل هذا آمن فقط لأن هناك 1 فقط الأعضاء وانها خصصت على كومة؟

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

المحلول

وانها خدعة C القديمة التي تم استخدامها للتغلب على عدم التوافر من صفائف طول متغير في سهل C. نعم، كما أنها تعمل في C ++ طالما كنت تستخدم بنيات مخصص مناسبة (مثل تخصيص مجموعة من ذاكرة الخام لل الحجم المطلوب ثم newing وضع الكائن في هناك). انها آمنة طالما كنت لا يهيمون على وجوههم خلال نهاية الذاكرة المخصصة، لكنها لا تميل للتشويش على الأقل بعض مصححات الذاكرة.

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

وأنا ولكن مشكوك فيها قليلا عن تنفيذ وظيفة مصنع - وأفترض حجم 'المعلمة هي في الواقع حجم مجموعة المرجوة؟ أيضا، لا ننسى أن كنت قد لتحرير الذاكرة أعلاه باستخدام 'الحرة' وليس 'حذف'، على الرغم من أن الأخير قد عمل في معظم الحالات.

واذا لم يكن هناك سبب مقنع لماذا الذاكرة يجب أن تدار بهذه الطريقة، وأنا ببساطة استبدال مجموعة مع الأمراض المنقولة جنسيا :: ناقلات.

نصائح أخرى

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

والهيكل الخاص بك هو غير POD (أنه يحتوي على الفئة الأساسية) ولذا فإنني لن أوصي به.

وبالإضافة إلى ذلك، إذا قمت بإنشاء مثل هذه الحالات

return new(malloc(__builtin_offsetof(StringChild ,iBuf[size]))) StringChild();

ويجب عليك التأكد من أن الذاكرة التي حصل عليها malloc يجب الافراج مع مجانا، لذلك حذف الحالات الخاصة بك مثل هذا:

obj->~StringChild();
free(obj);

وربما كنت ترغب في استخدام ::operator new() لتخصيص

وبالمعنى الدقيق للكلمة، منذ مشتق من StringChild StringBase انها ليست آمنة. المعيار C ++ لا يحدد تخطيط لsubobjects الفئة الأساسية. البند 10 الفقرة 3:

<اقتباس فقرة>   

والترتيب الذي يتم تخصيص subobjects الفئة الأساسية في الكائن الأكثر المشتقة (1.8) غير محدد.

إذا كانت StringChild البنية POD، فإن مثل هذه التقنية ستكون آمنة.

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