استرداد قيم متغيرات const الثابتة في مُنشئ متغير ثابت
-
27-09-2019 - |
سؤال
أفهم أن الكود أدناه سيؤدي إلى خطأ تجزئة لأنه في 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;
لا الحل هو مؤشر ترابط آمن.
نصائح أخرى
ما هو خطأ التجزئة الذي تتحدث عنه؟ لن يتم تجميع الكود الخاص بك ببساطة ، لأن أعضاء B
(و B
نفسها) ليست أعلن قبل A::A()
. المترجم ببساطة لن يعرف ماذا B
هو.
إذا قمت بتبادل تعريفات A
و B
, ، ثم يجب تجميع الكود ويعمل بشكل جيد. طالما أن كل شيء في وحدة الترجمة نفسها ، لا ينبغي أن تكون هناك أي مشاكل في أمر التهيئة ، على افتراض أن تعريفات من الأعضاء الثابتة B
تسبق تعريف من C::s_A
. تتم تهيئة الكائنات المحددة في نفس وحدة الترجمة بترتيب تعريفها ، مما يعني أنه بحلول الوقت A::A()
يبدأ ، أعضاء ثابتون B
تمت تهيئتها بالفعل. لا يوجد أي احتمال لخطأ التجزئة في هذه الحالة كما هو موضح.
إذا كنت تحصل على خطأ تجزئة ، فيجب أن تفعل شيئًا مختلفًا. ترتيب التعريف مختلف؟ وربما وحدات ترجمة متعددة؟ بعد/صف الرمز الحقيقي.