Получение значений преобразования статических кондентов на конструктор статической переменной
-
27-09-2019 - |
Вопрос
Я понимаю, что код ниже приведет к неисправности сегментации, потому что на CSTR a, b :: символ еще не инициализирован. Но почему?
На самом деле A - это объект, который служит картой, которая отображает символы классов, таких как B до их соответствующих идентификаторов. C Держите эту карту (а) Static-Ly так, что она может обеспечить отображение в качестве функции класса.
Основная функция A - служить карту для C, которая инициализирует себя при запуске. Как я могу сделать это без ошибки сегментации, при условии, что я все еще могу использовать B :: ID и B :: Символ в коде (нет #define Pls)?
(PS. Предположим, я реализовал включить охранников)
//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
уже инициализированы. Там нет потенциала для ошибки сегментации в этом случае, как представлено.
Если вы получаете ошибку сегментации, вы должны делать что-то по-другому. Порядок определения отличается? Множественные переводки могут быть? Пост / описать реальный код.