سؤال

لقد جئت من عالم .NET وأنا جديد على الكتابة C ++. أنا فقط أتساءل ما هي اتفاقيات التسمية المفضلة عندما يتعلق الأمر بتسمية المتغيرات المحلية وأعضاء الهيكل.

على سبيل المثال ، فإن الرمز القديم الذي ورثته يحتوي على الكثير من هذه:

struct MyStruct
{
   TCHAR           szMyChar[STRING_SIZE];
   bool            bMyBool;
   unsigned long   ulMyLong;
   void*           pMyPointer;
   MyObject**      ppMyObjects;
}

قادمة من خلفية C# شعرت بالصدمة لرؤية المتغيرات مع التدوين المجري (لم أستطع التوقف عن الضحك على بادئة PP في المرة الأولى التي رأيتها فيها).

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

struct MyStruct
{
   TCHAR           MyChar[STRING_SIZE];
   bool            MyBool;
   unsigned long   MyLong;
   void*           MyPointer;
   MyObject**      MyObjects;
}

سؤالي: هل هذه (الطريقة السابقة) لا تزال طريقة مفضلة لتسمية المتغيرات في C ++؟

مراجع:

http://geosoft.no/development/cppstyle.html

http://www.syntext.com/books/syntext-cpp-conventions.htm

http://ootips.org/hungarian-notation.html

شكرًا!

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

المحلول

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

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

نصائح أخرى

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

لا.

int * i = 17;
int j = ***i;

دون حتى تحذير من المترجم (وقد يكون ذلك رمزًا صالحًا على الأجهزة المناسبة ...).

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

ما زلت أستخدمه محليًا في حالات قليلة حيث يتعين علي خلط متغيرات ING و Float التي لها أسماء متشابهة جدًا أو حتى متطابقة في مجال المشكلة ، على سبيل المثال

float fXmin, fXmax, fXpeak; // x values of range and where y=max
int   iXmin, iXMax, iXpeak; // respective indices in x axis vector

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

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

ما الذي يكره أو يسخر من "ppmyobjects" في هذا المثال بصرف النظر عن كونه قبيح إلى حد ما؟ ليس لدي آراء قوية في كلتا الحالتين ، لكنها تواصل معلومات مفيدة في لمحة عن أن "myobjects" لا.

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

يجب أن تبرز متغيرات الأعضاء الفئة / الهيكل - عادةً ما أقوم ببلاغهم جميعًا مع M_
يجب أن تبرز المتغيرات العالمية - بادئة USUALL مع G_
يجب أن تبدأ المتغيرات بشكل عام بالحالة الأدنى
يجب أن تبدأ أسماء الوظائف بشكل عام بالحالة العليا
يجب أن تكون وحدات الماكرو وربما التعدادات العلوية
يجب أن تصف جميع الأسماء ما تفعله الوظيفة/المتغير ، ويجب ألا تصف نوعه أو قيمته.

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

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

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

أعتقد أنك ستظل تجد أن معظم المتاجر التي تبرم في Visual C ++ مع التدوين المجري أو على الأقل نسخة مخففة منها. في متجرنا ، يكون نصف تطبيقنا هو Legacy C ++ مع طبقة C# جديدة لامعة في الأعلى (مع طبقة C ++ المدارة في الوسط.) يستمر رمز C ++ لدينا في استخدام الترميز المجري ولكن رمز C# الخاص بنا يستخدم ترميزًا كما قدمت. أعتقد أنه قبيح ، لكنه متسق.

أقول ، استخدم ما يريده فريقك لمشروعك. ولكن إذا كنت تعمل على رمز Legacy أو الانضمام إلى فريق ، فقم بالتمسك بالأسلوب الموجود للتناسق.

كل شيء وصولاً إلى التفضيل الشخصي. لقد عملت في شركتين مع مخططات مماثلة ، حيث تم تسمية اسكواش الأعضاء على أنها m_varname. لم أر أبداً تدوينًا مجريًا قيد الاستخدام في العمل ، ولا يعجبني حقًا ، ولكن مرة أخرى إلى التفضيل. شعوري العام هو أن IDE يجب أن يهتم بإخبارك بنوعه ، طالما أن الاسم وصفي بما يكفي لما يفعله (m_color ، m_shouldberenamed) ، فهذا جيد. الشيء الآخر الذي أحبه هو الفرق بين متغير الأعضاء ، VAR المحلي والتسمية المستمرة ، لذلك من السهل رؤية ما يحدث في وظيفة ومن أين تأتي VARS. العضو: m_varname const: c_varname محلي: varname

I also prefer CamelCase, indeed mostly I've seen people using CamelCase in C++. Personaly I don't use any prefixes expect for private/protected members and interfaces:

class MyClass : public IMyInterface {
public:
    unsigned int PublicMember;
    MyClass() : PublicMember(1), _PrivateMember(0), _ProtectedMember(2) {}
    unsigned int PrivateMember() {
        return _PrivateMember * 1234; // some senseless calculation here
    }
protected:
    unsigned int _ProtectedMember;
private:
    unsigned int _PrivateMember;
};
// ...
MyClass My;
My.PublicMember = 12345678;

Why I decided to omit prefixes for public members: Because public members could be accessed directly like in structs and not clash with private names. Instead using underscores I've also seen people using first lower case letter for members.

struct IMyInterface {
    virtual void MyVirtualMethod() = 0;
};

Interfaces contains per definition only pure virtual methods that needs to be implemented later. However in most situation I prefer abstract classes, but this is another story.

struct IMyInterfaceAsAbstract abstract {
    virtual void MyVirtualMethod() = 0;
    virtual void MyImplementedMethod() {}
    unsigned int EvenAnPublicMember;
};

See High Integrity C++ Coding Standard Manual for some more inspiration.

Our team use Google C++ code convention:

This is a sample of variable name:

string table_name;  // OK - uses underscore.
string tablename;   // OK - all lowercase.

string tableName;   // Bad - mixed case.

If you use CamelCase the convention is to Capitalize the first letter for classes structs and non primitive type names, and lower case the first letter for data members. Capitalization of methods tends to be a mixed bag, my methods tend to be verbs and are already distingished by parens so I don't capitalize methods.

Personally I don't like to read CamelCase code and prefer underscores lower case for data and method identifiers, capitalizing types and reserving uppercase for acronyms and the rare case where I use a macro (warning this is a MACRO).

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