سؤال

أنا تعثرت على هذا قطعة من التعليمات البرمجية التي يبدو totaly كسر لي ، ولكن لم يحدث ذلك this هو null.أنا فقط لا أفهم كيف يمكن أن يكون هذا null

فمن داخل العادي استدعاء الأسلوب مثل

myObject->func();

داخل MyObject::func() لدينا

if (!this) { return false; }

هل هناك أي طريقة يمكن أن يكون السطر الأول لرمي NullPointerException بدلا من الذهاب داخل null(?) الطريقة ؟

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

المحلول

إذا كان لديك:

MyObject *o = NULL;

o->func();

وماذا سيحدث بعد ذلك يعتمد على ما إذا كان func هو الظاهري. إذا كان كذلك، فإنه سوف تعطل، لأنه يحتاج كائن للحصول على vtable من. ولكن إذا لم يكن الظاهري عائدات المكالمة مع هذا المؤشر لتعيين NULL.

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

وقد ترغب في إرسال وظيفة مساعد قابلة لإعادة الاستخدام:

void CheckNotNull(void *p)
{
    if (p == NULL)
        throw NullPointerException();
}

وبعد ذلك يمكنك استخدام ذلك في بداية وظيفة لفحص جميع الحجج، بما في ذلك this:

CheckNotNull(this);

نصائح أخرى

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

if(this == null)
   throw new NullPointerException;
if(!this)
   return false;

(هذا == NULL) غير معرف السلوك وفقا لمعيار.أعتقد أنك يجب أن إزالة هذا الاختيار :)

نفترض أننا جعل المكالمة التالية:

((CSomeClass*) 0)->method();

السلوك هو بالفعل غير معروف ، لذا لم يكلف نفسه عناء القيام التحقق من هذا == NULL في CSomeClass::الطريقة ؟

تحرير: أعتقد أن المترجم التعامل مع (0 == هذا) إذا كنت لا تستخدم المتغيرات عضو ، ولكن أين يمكن العثور على الجدول الظاهري المؤشر ؟ في هذه الحالة ، صفك لا يمكن استخدام polymoprhism.

ومن الممكن لthis أن تكون فارغة. وأظن أن هذا الرمز هو محاولة ل(سيئة) الكشف عن حالة سباق، حيث لم تنته بعد الكائن يتم تهيئة، أو تم حذفها.

وهذا المؤشر يمكن أن تصبح فارغة في مثل هذه الحالات:

class Test
{

public:
    bool f();

private:
    int m_i;
};


bool Test::f()
{
    if(!this)
    {
        return false;
    }

    m_i = 0;
    return true;

}


int main(int argc, char **argv)
{
    Test* p = new Test;
    delete p;
    p = NULL;

    p->f();
}

واعتقد شخص ما قام الإختراق سريع لتجنب لاستثناء انتهاك وصول.

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

ويجب تحقيق ما هو الخطأ حقا مع التعليمات البرمجية الخاصة بك بدلا من محاولة للتغلب على مثل هذا.

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