이건 싱글턴 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | template < typename T > class singleton { public: template < typename ...Args > static void create(Args... args) { unique_instance = std::make_unique<T>(args...); } static T& get_instance() { return *unique_instance; } static void destory() { unique_instance.reset(); } private: static std::unique_ptr<T> unique_instance; }; template < typename T > std::unique_ptr<T> singleton<T>::unique_instance = nullptr; | cs |
싱글턴으로 만들 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class any_class : public singleton<any_class> { public: any_class(int value) : value_{ value } { } void emit() { std::cout << value_ << std::endl; } private: int value_; }; | cs |
사용 예
1 2 3 4 5 6 7 8 | int main() { any_class::create(1); any_class::get_instance().emit(); return 0; } | cs |
코딩은 어렵게 하지 말고 쉽게쉽게 해 ㅎㅎ
와 type도 ...Arg 되는구나! 영 불편했었는데 쩐당 감사감사
아 그리고 unique_ptr 쓰려면 #include <memory>
저렇게 하면 종료 시 destory를 호출하지 않아도 메모리 해제까지 해줘
ㅊㄹ가 싱글톤 클래스 생성자에 값을 넣게 하고싶다고 했는데 그렇다는 건 생성 시점이 지정된다는 거잖아? 그러면 get_instance에서는 생성 과정 없이 하는게 맞다고 봐. 게임 프레임워크를 초기화 할 때 각 매니저 클래스의 생성자를 만드는 식으로 사용하려는 거 같으니까.
이거 멀티쓰레드에서 문제 있는 코드여
문제 없는데 create를 여러 곳에서 호출하는 것도 아니고 lock을 걸려면 매니저 클래스에 lock이 있어야지
응 무조건 한놈만 create를 부르면 상관없지
create()를 외부에 노출시킨다는 것 자체가 사실상 전역 객체와 크게 다르지 않을 뿐더러 create()를 무조건 한놈만 부른다는 보장이 없으면 사용하기 힘든 코드 같다. 이럴거면 차라리 전역객체로 std::unique_ptr<T>를 하나 두는게 낫지 않을까?
근데 이러면 외부에서 any_class(int value)로 any_class 객체를 만들 수 있는 거 아닌가요?
저걸 베이스로 noncopyable을 추가하면 되죠.
싱글턴이란게 원래 기능성과 편의성 적용성 사이에서 꼭 뭔가 트러블이 있게 마련.
컴파일러마다 민감한 부분도 있어서 컴파일 안되는 경우나 엉뚱한 스콥에서 해제될 수도 있음.
자기 경우에 알맞는 변종이 필요한거.