باستخدام memset على الهياكل في C ++
سؤال
مرحبا شباب. أنا أعمل على إصلاح التعليمات البرمجية القديمة لعملي. إنه مكتوب حاليًا في C ++. قاموا بتحويل تخصيص ثابت إلى ديناميكي لكنهم لم يحرروا memsets/memcmp/memcpy. هذا هو أول فترة تدريب على البرمجة الخاصة بي مع سؤالي الشبيه بالنيابة.
الكود التالي موجود في C ، لكنني أريد الحصول عليه في C ++ (قرأت أن Malloc ليس ممارسة جيدة في C ++). لدي سيناريوان: أولاً ، لقد خلقنا. ثم تستخدم & f من أجل ملء الصفر. والثاني هو مؤشر *pf. لست متأكدًا من كيفية تعيين PF على كل 0 مثل المثال السابق في C ++.
هل يمكنك القيام فقط pf = new foo
بدلا من malloc ثم اتصل memset(pf, 0, sizeof(foo))
?
struct foo { ... } f;
memset( &f, 0, sizeof(f) );
//or
struct foo { ... } *pf;
pf = (struct foo*) malloc( sizeof(*pf) );
memset( pf, 0, sizeof(*pf) );
المحلول
نعم ، ولكن فقط إذا كان فو هو جراب. إذا كان لديها وظائف افتراضية أو أي شيء آخر عن بعد C ++ ish ، فلا تستخدم Memset عليها نظرًا لأنه سيحدث في جميع أنحاء البنية/الفئة.
ما تريد أن تفعله بدلاً من Memset هو إعطاء Foo مُنشئًا لتهيئة أعضائه بشكل صريح.
إذا كنت ترغب في استخدام جديد ، فلا تنسى الحذف المقابل. من الأفضل أن تستخدم shared_ptr :)
نصائح أخرى
هل تستطيع؟ نعم ، ربما. هل يجب عليك؟ رقم.
على الرغم من أنه سيعمل على الأرجح ، إلا أنك تفقد الحالة التي قام بها المنشئ لك. إضافة إلى هذا ، ماذا يحدث عندما تقرر تنفيذ فئة فرعية من هذا الهيكل؟ ثم تفقد ميزة الشفرة القابلة لإعادة الاستخدام التي يوفرها C ++ OOP.
ما يجب عليك فعله بدلاً من ذلك هو إنشاء مُنشئ يقوم بتهيئة الأعضاء لك. وبهذه الطريقة ، عندما تقوم بإخلاص هذا الهيكل في وقت لاحق أسفل الخط ، يمكنك فقط استخدام هذا المنشئ لمساعدتك في بناء الفئات الفرعية. هذا هو رمز مجاني وآمن! استخدمه!
تحرير: التحذير من هذا هو أنه إذا كان لديك قاعدة كود ضخمة بالفعل ، فلا تغيره حتى تبدأ في التصنيف الفرعي للهياكل. إنه يعمل كما هو الآن.
نعم ، هذا سيعمل. ومع ذلك ، لا أعتقد أن Malloc هو الممارسة السيئة بالضرورة ، ولن أغيرها فقط لتغييرها. بالطبع ، يجب عليك التأكد من أنك تتطابق دائمًا مع آليات التخصيص بشكل صحيح (جديد> حذف ، malloc-> مجانًا ، إلخ).
يمكنك أيضًا إضافة مُنشئ إلى الهيكل واستخدامه لتهيئة الحقول.
يمكنك نيو فو (كما هي الطريقة القياسية في C ++) وتنفيذ مُنشئ يقوم بتشغيل FOO بدلاً من استخدامه memset.
على سبيل المثال
struct Something
{
Something()
: m_nInt( 5 )
{
}
int m_nInt;
};
لا تنسى أيضًا إذا كنت تستخدم الجديد للإتصال حذف عند الانتهاء من الكائن وإلا فسوف ينتهي بك الأمر بتسربات الذاكرة.