سؤال

أعتذر إذا كان هذا تم طرحها من قبل, أنا لست متأكدا تماما من المصطلحات أو كيفية طرح السؤال.

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

أتش تي أم أل ، طراز كائن المستند (DOM) هو مثال واحد ؛ آخر (المفتعلة) على سبيل المثال, لنفترض أن لدى هذه الفئات:

  • Entity
  • Person (فرعية من Entity)
  • Couple (فرعية من Entity)
  • Property
  • House (فرعية من Property)
  • Pet (فرعية من Property)
  • Car (فرعية من Property)

ومن هذه العلاقات:

  • Entity
    • 1 home من الطبقة House
    • 0 أو أكثر pets من الطبقة Pet
    • 0 أو أكثر cars من الطبقة Car
    • 0 أو أكثر children من الطبقة Person
  • Person
    • 0 أو 1 spouse من الطبقة Person
    • 0 أو 1 marriage من الطبقة Couple
    • 0 أو 1 parents من الطبقة Entity (في هذا النموذج الآباء لا وجود لها لو انهم ليسوا على قيد الحياة!)
  • Couple
    • 2 members من الطبقة Person
  • Property
    • 1 owner من الطبقة Entity

الآن بعد أن فكرت في هذه الأشياء وعلاقاتها ، أريد أن البدء في صنع هياكل البيانات و طرق و مجالات التعامل معها ، وهنا لا تضيع ، حيث يجب أن أتعامل مع تخصيص الذاكرة مدى الحياة وإدارة كل هذه الأشياء.يمكنك تشغيل في مشاكل مثل التالية:قد ترغب في وضع كائن في std::map أو std::vector, ولكن إذا كنت تفعل ذلك, أنا لا مؤشرات إلى تلك الكائنات لأنها يمكن أن تكون نقلت عندما خريطة أو ناقلات تنمو أو تنكمش.

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

غير المقدمة.أو هل هناك مكتبات لجعل هذا النوع من الاشياء أسهل في C++?

تحرير: ثم لديك قضايا أخرى مثل العلاقات بين الكائنات من المرجح أن تكون قابلة للتغيير في كثير من الحالات ، عليك أن تفكر في المستقبل حول كيفية مراجع إلى الكائنات يجب أن يتم تخزين و ما هي الطرق التي ينبغي توفيرها من أجل الوصول إلى الكائنات من بعضها البعض.على سبيل المثال, إذا كان لدي مؤشر Person X و أريد أن تمثل مفهوم "تجد X طفل يدعى جورج" ، ثم لدي لتخزين اسم "جورج" بدلا من الطفل رقم:الأطفال قد تكون مخزنة في ناقلات ، وأنا قد تكون قادرة على الاتصال X. getChildCount() و X. getChild(0), ولكن "جورج" قد لا تكون دائما الطفل رقم 0 ، لأن الأطفال الآخرين قد تكون عبارة "جورج" في الطفل ناقلات.أو X قد يكون اثنين أو ثلاثة أو أربعة أطفال آخرين أيضا اسمه "جورج".أو "جورج" قد تغير اسمه إلى "أنتوني" أو "جورجينا".في كل هذه الحالات قد يكون من الأفضل استخدام نوع من فريدة من نوعها ثابتة الهوية.

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

  • كيف يكون كائن واحد مخزن مرجع إلى كائن آخر ، عندما تكون هذه الأشياء قد تكون جزءا من هياكل البيانات التي يتم تخصيصها
  • كيفية التعامل مع كائن عمر الإدارة ، عندما تكون هناك علاقات متبادلة بين الكائنات
هل كانت مفيدة؟

المحلول

كنت كتبت عن تخزين الكائنات من كائن نموذج داخل std::ناقل الخ.و مشاكل مع استخدام مؤشرات لهم.هذا يذكرني أنه من الجيد أن تقسيم الخاص بك C++ الطبقات إلى فئتين (أنا غير متأكد حول المصطلحات هنا):

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

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

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


نعود الآن إلى السؤال الخاص بك.

إذا كنت ترغب في تخزين البيانات في نموذج العلاقات المعقدة و طريقة سهلة لعمل الاستفسارات مثل "العثور على X طفل يدعى جورج", لماذا لا تنظر في الذاكرة بيانات علائقية ؟

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

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


بعض الأفكار لإدارة الذاكرة:

  • قوية الملكية:عندما يمكنك أن تعلن أن بعض الكيان يعيش فقط طالما صاحبها وليس هناك إمكانية مستقل القائمة مؤشرات إلى ذلك ، يمكنك حذف فقط في مالك المدمر (أو مع scoped_ptr).

  • شخص اقترح بالفعل smart_ptr.فهي كبيرة و يمكن استخدامها مع المحكمة الخاصة بلبنان الحاويات.فهي إشارة couter تقوم على الرغم من ذلك لا إنشاء دورات :-(.أنا لست على علم بأي تستخدم على نطاق واسع c++ التلقائي المؤشرات التي يمكن التعامل مع دورات.

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

نصائح أخرى

هناك حوالي مليون دولار (في تقدير متحفظ) النهج هذا.أنت تسأل: "كيف يمكنني تصميم البرامج في C++".والجواب هو أنا خائف "ما هو البرنامج ذاهب إلى القيام به؟" - ببساطة مع العلم أن كنت ترغب في التعامل مع الأشخاص والمنازل ليست كافية.

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

يبدو لي أن تخزين البيانات في قاعدة البيانات باستخدام نوع object-relational mapping, قد يكون هناك خيار آخر للنظر في.

هل يمكن استخدام دفعة::shared_ptr لمعالجة مشاكل الذاكرة.ثم يمكنك بحرية نسخ shared_ptr حول العودة من الوظائف استخدامه بمثابة المتغير المحلي ، إلخ.

A Person ثم يمكن أن يكون std::map< string, boost::shared_ptr<Person> >, لذا X.getChild("George") ببساطة البحث عن الطفل في الخريطة عودة المؤشر.أعتقد أن تحصل على المفهوم ، لذلك سأترك بقية باعتبارها ممارسة لكم؛)

جايسون المصدر المفضل على هو C++ كتاب أسئلة وأجوبة.المشكلة هي أنك فعال يسأل "كيف يمكنني استخدام C++ وجوه المنحى البرمجة؟"

أفضل ما يمكن القول في ذلك والجواب هو هذا:

كل هذه الأمور ستكون دروس في C++, والعلاقات الخ سوف تبدو الكثير مثل القمامة التي تم جمعها لغات كنت تستخدم:إذا كنت في حاجة الى العلاقة بين العبد ولده اسمه "جورج" ، يمكنك اختيار بنية البيانات التي يمكن تخزينها الأشخاص أو تشايلدز فهرستها من قبل الاسم.

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

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