دليل أنماط Google في C ++. الجزء 9

الجزء 1. مقدمة
...
الجزء 8. التسمية
الجزء 9. التعليقات
...


هذه المقالة هي ترجمة لجزء من دليل أنماط Google بلغة C ++ إلى الروسية.
المقالة الأصلية (شوكة على جيثب) ، ترجمة محدثة .

تعليقات


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

علِّق على الكود مع مراعاة قرائها التاليين: المبرمجين الذين يحتاجون إلى فهم الكود. ضع في اعتبارك أنه يمكنك أن تكون القارئ التالي!

نمط التعليق


استخدم إما // أو / * * / حتى يتم انتهاك التوحيد.

يمكنك استخدام إما // أو / ** / ، ولكن / / الأفضل بكثير . ومع ذلك ، قم دائمًا بمحاذاة أسلوب تعليقك مع الشفرة الحالية

تعليقات في رأس الملف


أدخل رأس ترخيص في أعلى كل ملف.

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

المعلومات القانونية وقائمة المؤلفين


يجب أن يحتوي كل ملف على معلومات الترخيص. يعتمد تنسيق الوصف على الترخيص المستخدم في المشروع. قد يكون لكل ترخيص (Apache 2.0 ، BSD ، LGPL ، GPL ، إلخ) متطلبات التصميم الخاصة به.

إذا قمت بإجراء تغييرات كبيرة على الملف ، ففكر في حذف قائمة المؤلفين السابقة. قد لا تحتوي الملفات المحدّثة على ذكر لحقوق الطبع والنشر وقائمة من المؤلفين.

محتويات الملف


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

لا تقم بتكرار التعليقات في ملفات .h و .cc - تصبح التعليقات مختلفة بمرور الوقت.

تعليقات الطبقة


يجب أن يكون كل إعلان صفي (باستثناء الإعلانات الواضحة للغاية) مصحوبًا بتعليق وما الهدف من الفصل وكيفية استخدامه.

//   GargantuanTable. // : // GargantuanTableIterator* iter = table->NewIterator(); // for (iter->Seek("foo"); !iter->done(); iter->Next()) { // process(iter->key(), iter->value()); // } // delete iter; class GargantuanTableIterator { ... }; 

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

يمكنك أيضًا تقديم أمثلة على الكود القصير في تعليق الفصل لإظهار مدى سهولة استخدام الفصل.

بشكل عام ، يتم تعريف / تعريف فئة في ملفات مختلفة ( .h و .cc ). يجب أن تكون التعليقات التي تصف استخدام الفصل بجانب تعريف الواجهة. يجب أن تكون التعليقات على تعقيدات التنفيذ قريبة من كود الأساليب نفسها.

تعليقات وظيفة


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

إعلان وظيفة


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

في التعليق على إعلان الوظيفة ، لاحظ ما يلي:

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

مثال:

 //    .    //   .    //    GargantuanTable  . // //      . // //    : // Iterator* iter = table->NewIterator(); // iter->Seek(""); // return iter; //         , //    NewIterator()     . Iterator* GetIterator() const; 

ومع ذلك ، لا تمضغ الأشياء الواضحة.

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

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

تعريف الوظيفة


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

لاحظ أنه يجب ألا تكرر التعليق على إعلان الوظيفة (من ملف .h أو ما شابه ذلك) ، فمن الممكن أن تصف بإيجاز ما تقوم به الوظيفة ، ولكن الشيء الرئيسي هو أن يتم إخبارك بكيفية القيام بذلك.

تعليقات على المتغيرات


بطريقة جيدة ، يجب أن يقول الاسم المتغير على الفور ما هو ولماذا ، ومع ذلك ، في بعض الحالات ، يلزم وجود تعليقات إضافية.

عضو بيانات الفصل


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

من ناحية أخرى ، سيكون وصف القيم الخاصة (وغير الواضحة) مفيدًا (nullptr أو -1). على سبيل المثال:

 private: //       // -1 - ,         int num_total_entries_; 

المتغيرات العالمية


يجب تعليق جميع المتغيرات العالمية على الغرض منها و (إن لم تكن واضحة) لماذا يجب أن تكون عالمية. على سبيل المثال:

 //   ,     const int kNumTestCases = 6; 

تعليقات على التنفيذ


قم بالتعليق على تنفيذ وظيفة أو خوارزمية في حالة وجود تعليمات برمجية غير واضحة ومثيرة للاهتمام ومهمة.

تعليقات وصفية


يجب أن تسبق كتل التعليمات البرمجية المعقدة أو غير القياسية تعليق. على سبيل المثال:

 //    2.  x    for (int i = 0; i < result->size(); ++i) { x = (x << 8) + (*result)[i]; (*result)[i] = x >> 1; x &= 1; } 

خط التعليقات


يُنصح بتكميل سطور الكود بمعنى غير واضح مع التعليق (عادة ما يكون موجودًا في نهاية السطر) ، ويجب فصل هذا التعليق عن الكود بمسافة 2. على سبيل المثال:

 //   ,    mmap_budget = max<int64>(0, mmap_budget - index_->length()); if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock)) return; //    

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

تعليقات على وسيطات الوظيفة


عند تعيين وسيطة لدالة ما ، فإن النظر في الخيارات التالية:

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

النظر في الأمثلة التالية:

 //    ? const DecimalNumber product = CalculateProduct(values, 7, false, nullptr); 

لنجرب تمشيط الكود:

 ProductOptions options; options.set_precision_decimals(7); options.set_use_cache(ProductOptions::kDontUseCache); const DecimalNumber product = CalculateProduct(values, options, /*completion_callback=*/nullptr); 

ما لا تفعل


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

دعونا نقارن:

 //    . <-- :  ! auto iter = std::find(v.begin(), v.end(), element); if (iter != v.end()) { Process(element); } 

مع هذا:

 //  (Process) "element"     auto iter = std::find(v.begin(), v.end(), element); if (iter != v.end()) { Process(element); } 

كود الوصف الذاتي لا يحتاج إلى تعليقات على الإطلاق.
قد يكون التعليق على الكود أعلاه واضحًا بشكل عام (وليس ضروريًا):

 if (!IsAlreadyProcessed(element)) { Process(element); } 

علامات الترقيم والهجاء والقواعد


انتبه إلى علامات الترقيم والإملاء والقواعد: من الأسهل قراءة التعليقات المكتوبة بشكل صحيح.

يجب أن تكون التعليقات مكتوبة كقصة: مع الترتيب الصحيح للأحرف الكبيرة وعلامات الترقيم. في معظم الحالات ، تكون الجمل الكاملة أسهل في الفهم من شظايا العبارات. قد تكون التعليقات القصيرة ، مثل سطر بسطر ، أقل رسمية ، ولكن يجب أن تتبع الأسلوب الشائع.

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

تعليقات TODO


استخدم تعليقات TODO لرمز مؤقت أو حل جيد بما فيه الكفاية (متوسط ​​، وليس مثالي).

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

 // TODO(kl@gmail.com):  "*"  . // TODO(Zeke)   . // TODO(bug 12345):   " ". 

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

ملاحظة:
- قد تؤدي الروابط إلى أقسام من الدليل لم تتم ترجمتها بعد.
- من الأفضل إجراء مناقشة للقضايا العامة في الجزء 1. مقدمة

Source: https://habr.com/ru/post/ar480424/


All Articles