سؤال

أنا أعمل في C++ وأريد معرفة ما إذا كانت القيمة العددية (على سبيل المثال a double) "محدد" أم لا.أحتاج أيضًا إلى أن أكون قادرًا على "إلغاء تعريفه" إذا لزم الأمر:

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

هل من الممكن في C++؟

شكرًا

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

المحلول

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

واما هل يمكن أن يكون قيمة غير محددة والتي يمكنك تهيئة شريط لفي منشئ، وعادة -1.0 أو شيئا من هذا القبيل.

إذا كنت تعرف أن calculate_bar يعود أبدا القيم السلبية التي يمكن تنفيذ وظيفة غير معروف باعتباره الاختيار <0.0.

وحل أعم هو وجود منطقي قائلا ما إذا كان تعريف شريط بعد أن كنت تهيئة إلى false في منشئ وعند أول تعيينها تقوم بتغييره إلى true. تعزيز :: اختياري يفعل ذلك في طريقة أنيقة قالب.

وهذا ما رمز المثال لديك ستبدو.

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}

نصائح أخرى

وكما أشار آخرون، لا يوجد شيء مثل حالة "غير محددة". ولكنك قد ترغب في النظر في <لأ href = "http://www.boost.org/doc/libs/1_35_0/libs/optional/doc/html/boost_optional/examples.html#boost_optional.examples.optional_local_variables" يختلط = "noreferrer"> boost.optional

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

وتحرير: والامر متروك للمبرمج للتعامل مع الدولة الكائن في المنشئات و / أو أساليب التهيئة اليدوية مثل init()

لماذا لا تحافظ على علم مستقل أن يحصل على تهيئة إلى false ثم يحصل على مجموعة صحيح عندما يتم احتساب بار. ويمكن بعد ذلك أن "undefed من خلال تحديد العلم إلى false مرة أخرى.

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;

ولم يكن لديك C ++ حالة "غير محددة" لأنواع بدائية. الأقرب المتاحة لتعويم / مزدوجة سيكون NAN، ولكن هذا في الحقيقة معنى مختلف.

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

ويجب أن تفعل ذلك باستخدام منطقي إضافية.

لتنفيذ باستخدام منطقية إضافية، قد تتمكن من محاولة المنطق مثل القالب التالي:

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};

يمكنك تجربة البناء على لغة الاستخدام لأول مرة والكتابة get_bar() من هنا:

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

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

تحديث:

تم تغيير قيمة الإرجاع إلى double & للسماح لك بالتعديل bar.

وتهيئة bar إلى بعض القيمة التي لا يمكن أبدا أن تحدث عند استدعاء الدالة something() في منشئ.

وعلى سبيل المثال:

Foo(): bar(-1)
{
}

وثم تحقق ل-1 القيمة في وظيفة get_bar.

و(هممم كما سجلت Laserallan أن الجواب 1 دقيقة قبل :-( ؛-))

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