سؤال

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

أنا الغريب إذا كان هناك طريقة جيدة في C++ لتخزين البيانات البديل عن مثل هذا الوضع.أود البديل لاستخدام المكتبات القياسية ، لذلك أنا تجنب COM, Ole, و SQL البديل الأنواع المتوفرة.

بلدي الحل الحالي تبدو شيئا مثل هذا:

enum MetaValueType
{
    MetaChar,
    MetaString,
    MetaShort,
    MetaInt,
    MetaFloat,
    MetaDouble
};

union MetaUnion
{
    char cValue;
    short sValue;
    int iValue;
    float fValue;
    double dValue;
};

class MetaValue
{
...
private:
    MetaValueType ValueType;
    std::string StringValue;
    MetaUnion VariantValue;
};

على MetaValue فئة مختلفة الحصول على وظائف من أجل الحصول على تخزينها حاليا البديل قيمة ، ولكن ينتهي كل الاستعلام عن قيمة كتلة كبيرة من if/else if البيانات إلى معرفة القيمة التي أنا أبحث عن.

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

وقد أي شخص تنفيذها أو رأيت شيئا نظافة استخدام C++ متغير نوع البيانات باستخدام معيار المكتبات ؟

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

المحلول

واعتبارا من C ++ 17، هناك std::variant .

إذا لا يمكنك استخدام ذلك حتى الآن، قد ترغب <لأ href = "http://www.boost.org/doc/libs/1_36_0/doc/html/variant.html" يختلط = "نوفولو noreferrer" > Boost.Variant . ويرد مماثلة، ولكن واضح، اكتب لتعدد الأشكال النمذجة عن طريق std::any (وو ، قبل C ++ 17، Boost.Any ).

وكما مؤشر إضافي، يمكنك البحث عن " محو ".

نصائح أخرى

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

مشتركة مخصصة النهج التالية تعديل نمط مصنع:

  1. إنشاء واجهة قاعدة عامة كائن أيضا بتغليف نوع الكائن (سواء باعتبارها enum) ، أو باستخدام 'typeid' (الأفضل).
  2. الآن تنفيذ واجهة باستخدام قالب Derived فئة.
  3. إنشاء مصنع فئة مع templateized create وظيفة مع التوقيع:

template <typename _T> Base * Factory::create ();

هذا داخليا يخلق Derived<_T> الكائن على كومة ، retuns ديناميكية يلقي المؤشر.تتخصص هذه لكل فئة تريد تنفيذها.

وأخيرا تحديد Variant المجمع الذي يحتوي على هذا Base * مؤشر يحدد قالب وتعيين المهام.وظائف فائدة مثل getType(), isEmpty(), والتنازل المساواة بين المشغلين ، إلخ يمكن أن تنفذ بشكل مناسب هنا.

اعتمادا على الأداة وظائف المصنع التنفيذ ، دعم الطبقات سوف تحتاج إلى دعم بعض الوظائف الأساسية مثل الإحالة أو نسخ البناء.

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

وC ++ 17 لديها الآن std::variant الذي هو بالضبط ما كنت أبحث عنه.

الأمراض المنقولة جنسيا :: البديل

وعلى الرغم من أن السؤال قد أجاب لفترة طويلة، للسجل وأود أن أشير إلى أن <لأ href = "http://doc.qt.io/qt-5/qvariant.html" يختلط = "نوفولو "> QVariant أيضا يفعل ذلك.

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