CodeInside
@CodeInside

Как создать проинициализированное статическое поле?

Пишу эмулятор Bash под Windows. Есть класс Command, который состоит с оператора, вектора аргументов, и вектора опций. В этом классе есть метод isOperatorRegistered(), который проверяет зарегистрирован ли полученный оператор. Колд этого метода (ну и вспомогательного):
bool Command::isOperatorRegistered()
{
	bool isOperator_Registered = false;

	/*static*/ std::vector<std::string> registeredOperators;
	fillRegisteredOperatorsVector(registeredOperators);

	if (std::find(registeredOperators.begin(), registeredOperators.end(), operator_) == registeredOperators.end())
		isOperator_Registered = false;
	else
		isOperator_Registered = true;

	return isOperator_Registered;
}

void fillRegisteredOperatorsVector(std::vector<std::string>& registeredOperators)
{
	registeredOperators.reserve(6);

	registeredOperators.push_back("pwd");
	registeredOperators.push_back("ls");
	registeredOperators.push_back("cd");
	registeredOperators.push_back("cp");
	registeredOperators.push_back("mw");
	registeredOperators.push_back("rm");
}

Да, fillRegisteredOperatorsVector выглядит как костыль, но всё же суть не в том. Логично было бы, чтобы существовало статическое поле-вектор registeredOperators, ибо оно общее для всех экземпляров класса и нету смысла его дублировать. Но получается, что клиенту класса нужно будет самому вручную его инициализировать. Или это можно сделать и внутри класса? Если да, то как? Если нет, то как правильно спроектировать этот момент?
  • Вопрос задан
  • 235 просмотров
Решения вопроса 1
@Xano
"Или это можно сделать и внутри класса? "
//header
class Foo
{
static int Bar;
};
//source
int Foo::Bar = 0; //инициализация статической переменной


Можно проинициализировать статтическую переменную в функции:
std::vector< int > initializeBar()
{
    std::vector< int > res;
    res.push_back( 1 );
    res.push_back( 2 );
    return res;
}
void foo()
{
    static std::vector< int > Bar = initializeBar(); //или можно просто = { 1, 2}, например
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@Ariox41
Самый простой и надежный вариант - Синглтон Майерса:
std::vector<std::string>& getStaticMyVector (){
   static std::vector<std::string> staticVector = {"", ""};
   return v;
}

Дальше в любой функции можно получить статический вектор, вызвав getStaticMyVector ().

Если инициализация более сложная, можно сделать примерно так:
std::vector<std::string>& getStaticMyVector (){
   auto init = []{
     std::vector<std::string> v;
     v.push_back(" ");
     return v;
   };
   static std::vector<std::string> staticVector = init();
   return v;
}
Ответ написан
Комментировать
@alex-t
Прогр. в команде rco.ru
2 варианта на выбор:
class Foo
{
	static boost::array<std::string,3> a3;
	static std::vector<std::string> v3;
};
boost::array<std::string,3> Foo::a3 = {"aa", "bb", "cc"};
std::vector<std::string> Foo::v3 = boost::assign::list_of("aa")("bb")("cc");


Можно просто С-массив из const char * проинициализировать первым способом, но с ним чуть сложнее работать.
А проверку наличия надо не через std::vector, а через std::set (вторым способом тоже можно заполнить).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы