سلسلة CONST العالمية ورائحة سيئة بالنسبة لي، هل هي آمنة حقا؟

StackOverflow https://stackoverflow.com/questions/1028443

سؤال

وأنا استعراض كود الزملاء في، وأنا أرى أن لديه عدة ثوابت محددة في نطاق عالمي على النحو التالي:

const string& SomeConstant = "This is some constant text";

وشخصيا، وهذا رائحة سيئة بالنسبة لي لأن المرجعية ويشير إلى ما أفترض هو "مجهول" وجوه شيدت من مجموعة شار معين.

ونحوي، انها قانونية (على الأقل في VC ++ 7)، ويبدو أن تشغيل، ولكن في الحقيقة كنت قد وليس له إزالة ولذلك ليس هناك غموض بشأن ما تقوم به.

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


وهكذا ويمكن أيضا أن تكون معممة سؤالي لحياة الكائن المجهول. لا تملي مستوى عمر كائن مجهول؟ كان يمكن أن يكون نفس العمر مثل أي كائن آخر في هذا النطاق نفسه؟ أم أنها فقط نظرا لعمر التعبير؟


وأيضا، عند القيام بأنها المحلية، فإنه من الواضح أنه راقب بشكل مختلف:

class A
{
    string _str;

public:
    A(const string& str) :
        _str(str)
    {
        cout << "Constructing A(" << _str << ")" << endl;
    }

    ~A()
    {
        cout << "Destructing A(" << _str << ")" << endl;
    }
};

void TestFun()
{
    A("Outer");
    cout << "Hi" << endl;
}

ويظهر:

وبناء ألف (الخارجي)؛ التدمير A (الخارجي)؛ مرحبا

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

المحلول

وانها قانونية تماما. لن دمرت حتى ينتهي البرنامج.

وتحرير: <م> نعم ، ما يضمن ما يلي:

<اقتباس فقرة>   

و"جميع الأشياء التي ليس لديها ديناميكية   مدة التخزين، لم يكن لديك موضوع   مدة التخزين، وليست محلية   لديهم مدة تخزين ثابتة. ال   يجب تخزين هذه الكائنات آخر   لمدة البرنامج   (3.6.2، 3.6.3) ".

- 2008 الفريق مشروع، القياسية ل لغة البرمجة C ++ ، § 3.7.1 ص. 63

وكما ذكر مارتن، وهذا ليس هو الحل كله. مشروع معيار تلاحظ (الفقرة 12.2، ص 250-1.):

<اقتباس فقرة>   

و"يتم إنشاء المؤقتات من نوع فئة   في سياقات مختلفة: ملزمة لrvalue   إلى مرجع (8.5.3) [...] وحتى عندما   إنشاء كائن مؤقت   يتم تجنب (12.8)، كل الدلالي   يجب احترام القيود كما لو   وقد تم إنشاء كائن مؤقت.   [...] يتم تدمير الأشياء المؤقتة   والخطوة الأخيرة في تقييم   كامل التعبير (1.9) أن (مفرداتيا)   يحتوي على نقطة حيث كانوا   خلقت. [...] وهناك سياقين   حيث يتم تدمير المؤقتة المتقبلة في   نقطة erent دي وما يليها من نهاية   كامل التعبير. [...] الثاني   السياق هو عندما يكون المرجع هو المربوطة   إلى مؤقتة. مؤقت التي   لا بد من الإشارة أو   مؤقتة وهذا هو الكائن الكامل   من subobject التي الإشارة   لا بد قائما لعمر   الإشارة إلا إد فاي كما SPECI   أدناه. "

واختبرت في غرام ++ إذا كان ذلك يجعلك تشعر بأي أفضل. ؛)

نصائح أخرى

ونعم هو صحيح وقانوني.

const string& SomeConstant = "This is some constant text";

// Is equivalent too:

const string& SomeConstant = std::string("This is some constant text");

وهكذا كنت تقوم بإنشاء كائن مؤقت.
لا بد هذا الكائن مؤقت لCONST ووبالتالي تمت ديمومته تمديد لعمر المتغير لا بد منه أيضا (أي أطول من التعبير الذي أنشئت من أجله).

وومضمونة على ذلك المعيار.

ملاحظة:

وعلى الرغم من أنه هو قانوني. أنا لن استخدامها. والحل easist يكون لتحويله إلى الأمراض المنقولة جنسيا CONST :: سلسلة.

الاستخدام:

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

وعلى الرغم من أنه من الناحية التقنية قد يكون التقنى قبل هذا استخدامك للفي المنشئات / يجب أن يخفف تالفة من كائنات عمومية مع مشكلة معروفة من أجل تهيئة المتغير العالمي.

أفكار إضافية:

وهذا من جهة أخرى لا تعاني من المشكلة:

char const* SomeConstant = "This is some constant text";

ويمكن استخدامها في أي لحظة. مجرد التفكير.

قد يكون قانونيا، ولكن لا يزال القبيح. يستبعد المرجع!

const string SomeConstant = "This is some constant text";

وانها قانوني بقدر ما هو قبيح.

وانها قانوني لتمديد متغير مؤقت مع إشارة const، ويستخدم هذا عن طريق ScopeGaurd رؤية هذا التفسير الرائع الذي قدمه عشب سوتر دعا مرشح لل"معظم const أهمية" .

وأن يقال هذه الحالة المحددة هو إساءة استخدام هذه الميزة من C ++ ويجب إزالة إشارة ترك const string عادي.

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

حسنا، والناس يصحح لي إذا أنا قبالة نهاية عميق، ولكن هنا استنتاجاتي الاستماع إلى كل من الردود ممتازة الخاص بك:

وA) هو نحويا ومنطقيا القانوني، وويمتد عمر مؤقت / مجهولة المصدر من وراء مستوى التعبير لحياة المرجع. أنا التحقق من ذلك في VC ++ 7 مع:

class A { 
    public: A() { cout << "constructing A" << endl; }
    public: ~A() { cout << "destructing A" << endl; }
};

void Foo()
{
    A();
    cout << "Foo" << endl;
}

void Bar()
{
    const A& someA = A();
    cout << "Bar" << endl;
}

int main()
{
    Foo();    // outputs constructing A, destructing A, Foo
    Bar();    // outputs constructing A, Bar, destructing A
    return 0;
}

B) على الرغم من أنه هو قانوني، يمكن أن يؤدي إلى بعض الالتباس لعمر الفعلي والإشارة في هذه الحالات أعطيكم أي فائدة معلنا أنها غير مرجعية، وبالتالي ربما ينبغي تجنب الإشارة وربما حتى تكون مساحة إضافية. منذ ليس هناك فائدة لذلك، فإنه من التشويش لا لزوم له.

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

وصوت الحق؟

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