استرداد قيم متغيرات const الثابتة في مُنشئ متغير ثابت

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

سؤال

أفهم أن الكود أدناه سيؤدي إلى خطأ تجزئة لأنه في CSTR من A ، B :: لم يتم تهيئة الرمز بعد. لكن لماذا؟

في الواقع ، A هو كائن يعمل كخريطة تقوم بتخطيط رموز فئات مثل B إلى معرفاتها. يحمل C هذه الخريطة (أ) ثابتة بحيث يمكن أن توفر رسم الخرائط كدالة فئة.

الوظيفة الأساسية لـ A هي أن تكون بمثابة خريطة لـ C التي تهيئة نفسها عند بدء التشغيل. كيف يجب أن أتمكن من القيام بذلك دون خطأ تجزئة ، شريطة أن لا يزال بإمكاني استخدام B :: id و B :: الرمز في الكود (لا #DEFINE PLS)؟

//A.h
    #include "B.h"
    class A
    {
    public:
      A()
      {
        std::cout<<B::ID<<std::endl;
        std::cout<<B::SYMBOL<<std::endl;
      }
    };

//B.h    
    class B
    {
    public:
      static const int ID;
      static const std::string SYMBOL;
    }

//B.cpp    
    #include "B.h"
    const int B::ID = 1;
    const std::string B::SYMBOL = "B";

//C.h    
    #include "A.h"
    class C
    {
    public:
      static A s_A;
    };

//C.cpp    
    #include "C.h"
    A C::s_A;

//main.cpp    
    #include "C.h"
    int main(int c, char** p)
    {
    }
هل كانت مفيدة؟

المحلول

استخدام التهيئة البطيئة لـ S_A. هذا قد يعمل:

class C
{
public:
  static A& getA() { static A s_A; return s_A; }
};

أو:

class C
{
public:
  static A& getA() 
  { 
    if( ps_A == NULL) ps_A = new ps_A; 
    return *ps_A; 
  }
private:
  static A* ps_A;
};

A* C::ps_A = NULL;

لا الحل هو مؤشر ترابط آمن.

نصائح أخرى

ما هو خطأ التجزئة الذي تتحدث عنه؟ لن يتم تجميع الكود الخاص بك ببساطة ، لأن أعضاء BB نفسها) ليست أعلن قبل A::A(). المترجم ببساطة لن يعرف ماذا B هو.

إذا قمت بتبادل تعريفات A و B, ، ثم يجب تجميع الكود ويعمل بشكل جيد. طالما أن كل شيء في وحدة الترجمة نفسها ، لا ينبغي أن تكون هناك أي مشاكل في أمر التهيئة ، على افتراض أن تعريفات من الأعضاء الثابتة B تسبق تعريف من C::s_A. تتم تهيئة الكائنات المحددة في نفس وحدة الترجمة بترتيب تعريفها ، مما يعني أنه بحلول الوقت A::A() يبدأ ، أعضاء ثابتون B تمت تهيئتها بالفعل. لا يوجد أي احتمال لخطأ التجزئة في هذه الحالة كما هو موضح.

إذا كنت تحصل على خطأ تجزئة ، فيجب أن تفعل شيئًا مختلفًا. ترتيب التعريف مختلف؟ وربما وحدات ترجمة متعددة؟ بعد/صف الرمز الحقيقي.

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