2016-07-28 10 views
3

특정 인스턴스의 생성자 안에 정적 멤버 변수를 초기화하려고합니다. 그게 나쁜 생각이야?인스턴스의 생성자 내에서 정적 멤버 초기화

상황은 다음과 같습니다. 이 클래스의 모든 인스턴스가 공유해야하는 정적 멤버 변수가 있습니다. 일반적으로 정적 인 초기화 도구를 사용합니다. 그러나 생성자가 호출 될 때까지 정적 객체를 만드는 데 필요한 정보가 없습니다. 물론 생성자가 호출 될 때마다 새 객체를 만들고 싶지 않으므로 이와 같은 작업을 수행하려고합니다. 나는 물론 xyz 알고

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); 
    } 
} 

Foo의 생성자에 다른 통화 다를 수 migth. 그건 내게 중요하지 않아.

이 나쁜 소프트웨어 디자인입니까? 생성자 내부에서 정적 객체를 초기화하는 것이 이상하게 느껴집니다. 그러나 싱글 톤 디자인 패턴과 크게 다르지 않습니다. 어쩌면 괜찮을까요? 코멘트들에 대한

편집

감사합니다. 사람들이이 디자인의 팬이 아닌 것 같습니다. 나는 Foo의 최초 인스턴스 생성 전에 한 번 Bar을 만들고 Foo의 생성자에서 매개 변수로 Bar *을 전달하도록 수정합니다. 각 FooBar에 대한 포인터를 가지며 모든 Foo이 모두 동일한 Bar을 가리키고 있는지 확인합니다. 그게 더 좋은가요?

+1

당신이 초기화를 수행하지 않습니다 마십시오. 너는 임무를 수행 할 것이다. – NathanOliver

+0

_ 초기화에 사용할 값을 어떻게 얻습니까? 런타임에만 사용할 수 있습니까? BTW 샘플은 컴파일되지 않습니다. –

+3

단일 스레드는 괜찮아 보입니다. 다중 스레드 경쟁 조건. –

답변

1

이 나쁜 소프트웨어 디자인입니까?

일반적으로 그렇습니다. 싱글 톤 패턴 또는 이러한 방식으로 정적 변수를 갖는 것이 많은 이유가 나쁜 디자인으로 간주됩니다.


는하지만 그것은 싱글 톤 디자인 패턴 다르지 않다. 어쩌면 괜찮을까요?

당신이 정말 싱글 톤 패턴은 오히려 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는 다음의 자신의 싱글를 구성해야하고, 필요할 때마다 당신이 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 디자인에 결함이 있음을 나타내는 지표이며 'Bar'는 'Foo'에 대한 정적 관계. 난 _real_ 싱글 톤 패턴과의 차이를 분명히하려고 노력했다. –