سؤال

هذا السؤال سبق الجواب هنا:

أنا أتعامل مع قاعدة رمز كبير يستخدم التالية بناء في جميع أنحاء

class MyClass
{
public:
  void f(int x);
private:
  int x;
};


void MyClass::f(int x)
{
'
'
  this->x = x;
'
'
}

أنا شخصيا كنت تستخدم دائما وبالتالي يفضلون شكل

class MyClass
{
public:
  void f(int x);
private:
  int _x;
};


void MyClass::f(int x)
{
'
'
  _x = x;
'
'
}

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

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

المحلول

الإصدار الخاص بك هو قليلا أكثر نظافة ، ولكن بينما كنت في ذلك:

  1. تجنب الرائدة تؤكد:_x على ما يرام حتى شخص يختار _MyField وهو اسم محجوز.أولية تؤكد يليه حرف غير مسموح به حسب اسم متغير.انظر: ما هي قواعد استخدام تسطير أسفل السطر في C++ معرف?
  2. جعل السمة الخاصة أو المحمية:التغيير آمنة إذا كان تجمع وعليك التأكد من واضع سيتم استخدامها.
  3. هذا-> قصة لها استخدام ، على سبيل المثال في قالب كود جعل اسم الحقل تعتمد على نوع الخاص بك (يمكن أن تحل بعض بحث القضايا).

مثال صغير من اسم القرارات التي يتم إصلاحها باستخدام صريح هذا-> (اختبار مع g++ 3.4.3):

#include <iostream>
#include <ostream>

class A
{
public:
  int g_;
  A() : g_(1) {}
  const char* f() { return __FUNCTION__; }
};

const char* f() { return __FUNCTION__; }
int g_ = -1;

template < typename Base >
struct Derived : public Base
{
  void print_conflicts()
  {
    std::cout << f() << std::endl; // Calls ::f()
    std::cout << this->f() << std::endl; // Calls A::f()
    std::cout << g_ << std::endl; // Prints global g_
    std::cout << this->g_ << std::endl; // Prints A::g_
  }
};

int main(int argc, char* argv[])
{
   Derived< A >().print_conflicts();
   return EXIT_SUCCESS;
}

نصائح أخرى

حقل التسمية لا علاقة له مع codesmell.كما نيل وقال مجال الرؤية هو فقط codesmell هنا.

هناك العديد من المواد المتعلقة اصطلاحات التسمية في C++:

الخ.

هذا الاستخدام من هذا هو تشجيع من قبل Microsoft C# معايير الترميز.لأنه رمز الوضوح, و المقصود هو أن تكون المعايير أكثر من استخدام m_ أو _ أو أي شيء آخر في الأعضاء المتغيرات.

بصراحة انا حقا لا نشدد في الأسماء على أي حال, أنا ليسبق كل أعضاء واحد 'm'.

الكثير من الناس استخدام هذا لأن في IDE فإنه سيتم تقديم قائمة من معرفات من الطبقة الحالية المنبثقة.

أنا أعرف أن أفعل في BCB.

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

شعوري الشخصي هو أن القتال الحالي الترميز الاتفاقية هو شيء يجب أن لا تفعل.كما ساتر/Alexandrescu يضعه في كتاب 'C++ الترميز الاتفاقيات:لا عرق الأشياء الصغيرة.أي شخص قادر على قراءة واحدة أو أخرى ، ما إذا كان هناك قيادة->' أو '_' أو أيا كان.

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

إذا كنت بعد كل شيء ، تجد هناك سبب وجيه لتغيير أنها لا تفعل ذلك يدويا.في أفضل الأحوال ، IDE الخاص بك يدعم هذا النوع من 'refactorings'.وإلا كتابة برنامج نصي لتغيير ذلك.البحث واستبدال يجب أن يكون الخيار الأخير.في أي حال, يجب أن يكون لديك نسخة احتياطية (المصدر التحكم) و نوع من الاختبار الآلي المرفق.وإلا فلن يكون متعة معها.

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

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

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

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


class MyClass{
public:  
  int x;  
  void f(int xval);
};
//
void MyClass::f(int xval){  
  x = xval;
}

في رأيي هذا يميل إلى إضافة فوضى إلى رمز ، لذا أنا أميل إلى استخدام مختلف أسماء المتغيرات (اعتمادا على الاتفاقية ، قد يكون من تسطير ، m_, أيا كان).

class MyClass
{
public:
  int m_x;
  void f(int p_x);
};


void MyClass::f(int p_x)
{
  m_x = p_x;
}

...هي طريقتي المفضلة باستخدام نطاق البادئات.m_ الأعضاء, p_ للمعلمة (استخدام بعض a_ عن الحجة بدلا من ذلك) ، g_ العالمية وأحيانا l_ المحلية إذا كان ذلك يساعد على سهولة القراءة.

إذا كان لديك اثنين من المتغيرات التي تستحق نفس الاسم ثم وهذا يمكن أن تساعد الكثير و يتجنب الحاجة إلى إجراء بعض الاختلاف عشوائية على معناها فقط لتجنب إعادة تعريف.أو حتى أسوأ من ذلك اللعين 'x2, x3, x4, الخ...

انها أكثر طبيعية في C++ أعضاء initialised على البناء باستخدام initialiser.

للقيام بذلك يجب عليك استخدام اسم مختلف عن اسم عضو متغير.

حتى على الرغم من أنني استخدم Foo(int x) { this.x = x; } في جافا, لا في C++.

الحقيقي رائحة قد تكون عدم استخدام initialisers والأساليب التي لا تفعل شيئا سوى تحور الأعضاء المتغيرات بدلا من استخدام this -> x نفسها.

أحد يعرف لماذا هو ممارسة عالمية في كل C++ المحل كنت في استخدام أسماء مختلفة منشئ الحجج الأعضاء المتغيرات عند استخدام مع initialisers?كانت هناك بعض C++ compilers الذي لم يعتمد عليه ؟

اليوم, معظم IDE المحررين اللون المتغيرات الخاصة بك للإشارة إلى أعضاء الفئة من المتغيرات المحلية.وهكذا والمنظمة البحرية الدولية لا البادئات أو 'this->' يجب أن تكون مطلوبة من أجل القراءة.

أنا لا أحب استخدام "هذا" لأنه الرجعية.إذا كنت البرمجة القديمة ج (تذكر C؟), و هل تريد أن تحاكي بعض من خصائص OOP إنشاء البنية مع عدة أعضاء (هذه هي مشابهة إلى خصائص الكائن) و يمكنك إنشاء مجموعة من الوظائف التي تأخذ كل مؤشر إلى أن البنية كأول الحجة (هذه هي مشابهة إلى أساليب من هذا الكائن).

(أعتقد أن هذه الرموز المميزة ل typedef الجملة صحيحة ولكن انها كانت فترة من الوقت...)

typedef struct _myclass
{
   int _x;
} MyClass;

void f(MyClass this, int x)
{
   this->_x = x;
}

في الواقع أعتقد أن كبار السن C++ compilers فعلا ترجمة التعليمات البرمجية الخاصة بك إلى النموذج أعلاه ثم يمر ذلك إلى C compiler.وبعبارة أخرى -- C++ إلى حد ما فقط النحوية السكر.لذلك أنا لست متأكدا لماذا أي شخص يريد أن البرنامج في C++ و العودة صراحة باستخدام "هذا" في التعليمات البرمجية أو ربما "النحوية Nutrisweet"

إذا كان لديك مشكلة مع اصطلاحات تسمية يمكنك محاولة استخدام شيء مثل التالي.

class tea
{
public:
    int cup;
    int spoon;
    tea(int cups, int spoons);
};

أو

class tea
{
public:
    int cup;
    int spoon;
    tea(int drink, int sugar);
};

أعتقد أنك حصلت على فكرة.انها في الاساس تسمية المتغيرات المختلفة ولكن "نفس" في المنطقي.وآمل أن يساعد.

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