2015-09-26 3 views
0

Итак, у меня есть класс со статическими переменными, причина, по которой они статичны, для (хотя может показаться, незначительной) эффективности (требуется только один раз загрузить нагрузку, уменьшить избыточность памяти в памяти того же файла).C++ Конструктор только для первого экземпляра?

В любом случае, что я хотел бы знать, есть ли способ проверить, была ли загружена переменная?

Или существует способ создания определенного конструктора, когда первый экземпляр этого класса создается, а другой используется, когда существуют другие экземпляры?

Если ни одно из них не подходит, каково решение?

+3

Статические переменные-члены построены и инициализируется перед вашим 'функция main' называется. Если 'main' был вызван, то статические переменные-члены были« загружены ». –

+1

Существует шаблон дизайна OneTon для эффективного проектирования кода, пожалуйста, пройдите через это: https://sourcemaking.com/design_patterns/singleton/cpp/1 – Nishant

+0

@ Nishant_b9: ... и затем отбросьте его как ужасную идею и забудьте вы когда-нибудь читали об этом. –

ответ

3

Если статические члены являются частными, и инициализирован в одной единице трансляции, как все функции членов вашего класса, то стандарт гарантирует, что статические члены будут инициализироваться, прежде чем они используются. См.: When are static C++ class members initialized?

Существуют и другие ситуации, когда эта гарантия не помогает вам (например, доступ к неличным статическим элементам из другой единицы перевода или из встроенных функций-членов).

Вы можете играть в игры с флагами isInitialized, но имейте в виду, что без дальнейшей работы это не будет поточно-безопасным.

Часто задаваемые вопросы по C++ рекомендует переносить статические экземпляры классов в функции, что гарантирует их инициализацию при первом использовании. например .:

Fred& x() 
{ 
    static Fred* ans = new Fred(); 
    return *ans; 
} 

Источник: https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use

0

Здесь вы идете:

class Test { 
    static bool isInitialized; 
public: 
    Test() { 
    if (!isInitialized) { 
     // do whatever you need here 
     // ... 
     isInitialized = true; 
    } 
    } 
}; 

bool Test::isInitialized = false; 
+0

@ MarcusMüller: еще раз? –

+0

John, извините за это :) Я просто ожидал увидеть этот шаблон (проверка статического набора в классе decl); Я также неправильно читаю ваш код, поэтому я собираюсь отменить свой голос. –

0

Вы можете сделать что-то вроде:

struct StaticData 
{ 
    // some variables 
}; 

class YourClass 
{ 
public: 
    YourClass(/*..*/) { 
     if (staticData == nullptr) { 
      staticData = std::make_unique<StaticData>(/*..*/) 
     } 
    } 
private: 
    static std::unique_ptr<StaticData> staticData; 
}; 

static std::unique_ptr<StaticData> YourClass::staticData; 
+0

Или просто создайте экземпляр, как правило, без динамического распределения, усложняющего ваш код. –

+0

@LightnessRacesinOrbit: Я подозреваю, что OP инициализирует его некоторыми аргументами. Но иначе вы правы. – Jarod42