2016-07-28 3 views
3

Я хочу инициализировать статическую переменную-член внутри конструктора конкретного экземпляра. Это плохая идея?Инициализировать статический член внутри конструктора экземпляра

Ситуация такова. У меня есть статическая переменная-член, которой должны делиться все экземпляры этого класса. Обычно я просто использую статический инициализатор. Но у меня нет необходимой информации, необходимой для создания статического объекта, пока не будет вызван конструктор. Но, конечно, я не хочу создавать новый объект каждый раз при вызове конструктора, поэтому я хочу сделать что-то вроде этого.

class Foo 
{ 
    static Bar * bar; 
    Foo(Xyz xyz); 
}; 

Bar * Foo::bar = nullptr; 

Foo::Foo(Xyz xyz) 
{ 
    if (Foo::bar == nullptr) 
    { 
     // initialize static bar 
     Foo::bar = new Bar(xyz); 
    } 
} 

Я знаю, конечно xyz migth быть различными для разных вызовов конструктора Foo. Для меня это не важно.

Это плохой дизайн программного обеспечения? Я чувствую себя немного странно, инициализируя статический объект внутри конструктора. Но это не отличается от шаблона дизайна синглтона. Так, может быть, все в порядке?

EDIT

Спасибо за комментарии, ребята. Кажется, люди не являются поклонниками этого дизайна. Я буду изменять его так, чтобы я создал Bar один раз перед самым первым экземпляром Foo и передал Bar * в качестве параметра в конструкторе Foo. У каждого Foo будет указатель на Bar, и я обязательно удостоверьтесь, что все Foo s все указывают на то же самое Bar. Это лучше?

+1

Обратите внимание, что вы не будете делать инициализацию. Вы будете выполнять задание. – NathanOliver

+0

Как вы получаете значение, которое должно использоваться для _initialization_? Доступен ли он только во время выполнения? Кстати, образец не будет компилироваться. –

+3

Одиночная резьба выглядит нормально. Состояние многопоточной гонки. –

ответ

1

Это плохой дизайн программного обеспечения?

В целом, это будет считаться да, да. Существует много причин, почему Singleton Pattern или имеющий статические переменные таким образом считается плохим дизайном.


Но это не то, что отличается от одноплодного шаблона дизайна. Так, может быть, все в порядке?

Если вы действительно хотите сделать что Singleton Pattern вам лучше использовать Scott Meyer's technique:

class Foo 
{ 
    static Bar* bar(Xyz xyz) { 
     static Bar barInstance(xyz); 
     return &barInstance; 
    } 
    Foo(Xyz xyz) : xyz_(xyz) {} 

    void baz() { 
     Bar* b = bar(xyz_); 
     // use b ... 
    } 

private: 
    Xyz xyz_; 
}; 

Этот код будет поточно, и избавляет от необходимости проверять на nullptr.


Хотя Bar должен составить Singleton на своем собственном то, и вы используете его в Foo всякий раз, когда необходимо:

class Bar { 
public: 
    static Bar& getInstance(Xyz xyz) { 
     static Bar barInstance(xyz); 
     return &barInstance; 
    } 

private: 
    Bar(Xyz xyz) : xyz_(Xyz) {} 
    Bar(const Bar&) delete; 
    Bar(Bar&&) delete; 
    Bar& operator=(const Bar&) delete; 
    Bar& operator=(Bar&) delete; 

    Xyz xyz_; 
}; 

class Foo { 
public: 
    Foo(Xyz xyz) barRef(Bar::getInstance(xyz)) { 
             // ^^^ Notice 1st instance of Foo created 
             //  wins to create the Bar actually 
    } 
private: 
    Bar& barRef; 
}; 
+0

* «Но у меня нет необходимой информации, необходимой для создания статического объекта до тех пор, пока конструктор не будет вызван» * ... – Jarod42

+1

@ Jarod42 Это индикатор, который является ошибочным, а «Бар» не должен быть в статическое отношение к 'Foo'. Я просто пытаюсь прояснить отличие от шаблона Singlereal. –

Смежные вопросы