U E D R , A S I H C RSS

Gof/Singleton


1. Singleton

1.1. Intent

ํด๋ž˜์Šค๋กœ ํ•˜์—ฌ๊ธˆ ์˜ค์ง ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ์„ ๊ฐ€์ง€๊ฒŒ ํ•˜๋ฉฐ, ์–ด๋””์„œ๋“ ์ง€ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•œ๋‹ค.

1.2. Motivation

๋ช‡๋ช‡ ํด๋ž˜์Šค๋“ค์— ๋Œ€ํ•ด์„œ ์˜ค์ง ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค ๋งŒ์„ ๊ฐ€์ง€๋Š” ๊ฒƒ์€ ์ค‘์š”ํ•œ ์ผ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, ์–ด๋–ค ์‹œ์Šคํ…œ์—์„  ์ˆ˜๋งŽ์€ ํ”„๋ฆฐํ„ฐ๋“ค์ด ์žˆ๋”๋ผ๋„ ๊ฑฐ๊ธฐ์—๋Š” ๋‹จ ํ•˜๋‚˜์˜ ํ”„๋ฆฐํ„ฐ ์Šคํ”Œ๋Ÿฌ๋งŒ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. OS์—์„œ ๋Œ์•„๊ฐ€๋Š” ํ™”์ผ์‹œ์Šคํ…œ์ด๋‚˜ ์œˆ๋„์šฐ ๋งค๋‹ˆ์ €์˜ ๊ฒฝ์šฐ๋„ ์˜ค์ง ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค (๋™์‹œ์— 2-3๊ฐœ์˜ ์œˆ๋„์šฐ๋งค๋‹ˆ์ €๊ฐ€ ๋Œ์ง„ ์•Š๋Š”๋‹ค.) ๋””์ง€ํ„ธ ํ•„ํ„ฐ์˜ ๊ฒฝ์šฐ์—๋„ A/D converter๋Š” ๋‹จ ํ•˜๋‚˜๋ฅผ ๊ฐ€์ง„๋‹ค.

์–ด๋–ป๊ฒŒ ์šฐ๋ฆฌ๋Š” ํด๋ž˜์Šค๋กœ ํ•˜์—ฌ๊ธˆ ๋‹จ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ์„ ๊ฐ€์ง€๋„๋ก ๋ณด์žฅํ•ด์ค„ ์ˆ˜ ์žˆ์„๊นŒ? ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋Ÿฌํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ธ๊ฐ€? global ๋ณ€์ˆ˜๋กœ ๋‘˜ ๊ฒฝ์šฐ ์–ด๋””์„œ๋“ ์ง€ ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๊ฒ ์ง€๋งŒ, global ๋ณ€์ˆ˜๋Š” ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋งŒ์„ ๊ฐ€์ง€๋„๋ก ํ•  ์ˆ˜ ์—†๋‹ค.

๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํด๋ž˜์Šค ์ž์‹ ์œผ๋กœ ํ•˜์—ฌ๊ธˆ ์ž๊ธฐ์ž์‹ ์˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ์œ ์ง€ํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ”์œผ๋กœ์„œ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์€ ๋ณด์ฆํ•œ๋‹ค. ๋˜ํ•œ, ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์ œ๊ณตํ•œ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ SingletonPattern์ด๋‹ค.

1.3. Applicability

SingletonPattern์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค.
  • ํด๋ž˜์Šค๊ฐ€ ์ •ํ™•ํžˆ ์˜ค์ง ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ์ด ์กด์žฌํ•ด์•ผ ํ•  ๋•Œ. ๊ทธ๋ฆฌ๊ณ  ์ž˜ ์•Œ๋ ค์ง„ ์—‘์„ธ์Šค ๋ฐฉ๋ฒ•์œผ๋กœ ์–ด๋””์„œ๋“ ์ง€ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๊ฐ€ ์„œ๋ธŒํด๋ž˜์‹ฑ์— ์˜ํ•ด ํ™•์žฅ๊ฐ€๋Šฅํ•ด์•ผ ํ•  ๊ฒฝ์šฐ. ๊ทธ๋Ÿฌ๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” ๊ทธ๋“ค์˜ ์ฝ”๋“œ ์ˆ˜์ •์—†์ด ํ™•์žฅ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

1.5. Participants

  • Singleton
    • Instance operation (ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ)์„ ์ •์˜ํ•œ๋‹ค. Instance ๋Š” ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ํ•ด๋‹น Singleton์˜ ์œ ์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.
    • Singleton ์ž์‹ ์˜ ์œ ์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฑ…์ž„์„ ๊ฐ€์ง„๋‹ค.

1.6. Collaborations

  • ํด๋ผ์ด์–ธํŠธ๋Š” ์˜ค์ง Singleton์˜ Instance operation์œผ๋กœ๋งŒ Singleton ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

1.7. Consequences

SingletonPattern์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์žฅ์ ์„ ๊ฐ€์ง„๋‹ค.
  1. ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ์ด ์˜ค์ง ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค์—๊ฒŒ๋กœ ์ œํ•œ๋œ๋‹ค. Singleton ํด๋ž˜์Šค๋Š” ์ž๊ธฐ ์ž์‹ ์˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ์บก์Аํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์–ธ์ œ, ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ•˜๋˜์ง€ ๊ทธ ์ ‘๊ทผ์ด ์—„๊ฒฉํ•˜๊ฒŒ ์ œ์–ด๋œ๋‹ค.
  2. namespace๋ฅผ ์ค„์ธ๋‹ค. SingletonPattern์€ global variable์„ ์ค„์ž„์œผ๋กœ์„œ global variable๋กœ ์ธํ•œ namespace์˜ ๋‚ญ๋น„๋ฅผ ์ค„์ธ๋‹ค.
  3. ๋ช…๋ น์–ด์™€ ํ‘œํ˜„์„ ํ™•์žฅ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. Singleton class๋Š” subclass๋  ์ˆ˜ ์žˆ๊ณ , ์ด ํ™•์žฅ๋œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ๋‹ค. run-time์ค‘์— ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  4. ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ๋งˆ์Œ์— ๋”ฐ๋ผ ์‰ฝ๊ฒŒ Singleton class์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜์ด์ƒ์„ ๋‘˜ ์ˆ˜๋„ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉํ•˜๋Š” ์ธ์Šคํ„ด์Šค๋“ค์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ๋™์ผํ•œ ์ ‘๊ทผ๋ฐฉ๋ฒ•์„ ์ทจํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ์ง€ Singleton ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š” operation๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.
  5. class operation ๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๋‹ค. ํŒจํ‚ค์ง€์—์„œ Singleton์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ์œ„ํ•œ ๋˜๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ class operation๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (C++์—์„œ์˜ static ํ•จ์ˆ˜๋‚˜ Smalltalk์—์„œ์˜ class method ๋“ฑ๋“ฑ) ํ•˜์ง€๋งŒ, ์ด๋Ÿฌํ•œ ์–ธ์–ด์ ์ธ ํ…Œํฌ๋‹‰๋“ค์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋””์ž์ธ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ ํž˜๋“ค์–ด์ง„๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ C++์—์„œ์˜ static method๋Š” virtual์ด ๋  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, subclass๋“ค์ด override ํ•  ์ˆ˜ ์—†๋‹ค.

1.8. Implementation

SingletonPattern ์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ๋“ค์ด ์žˆ๋‹ค.

1. unique instance์ž„์„ ๋ณด์ฆํ•˜๋Š” ๊ฒƒ. SingletonPattern์˜ ๊ฒฝ์šฐ๋„ ์ผ๋ฐ˜ ํด๋ž˜์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ™๋‹ค. ํ•˜์ง€๋งŒ ํด๋ž˜์Šค๋Š” ๋Š˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๊ฐ€ ์œ ์ง€๋˜๋„๋ก ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋œ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” operation์„ class operations์œผ๋กœ ๋‘๋Š” ๊ฒƒ์ด๋‹ค. (static member function์ด๊ฑฐ๋‚˜ class method) ์ด operation์€ unique instance๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋ฉฐ ์ด๋•Œ ์ด ๋ณ€์ˆ˜์˜ ๊ฐ’ (์ธ์Šคํ„ด์Šค)๋ฅผ ๋ฆฌํ„ดํ•˜๊ธฐ ์ „์— ์ด ๋ณ€์ˆ˜๊ฐ€ unique instance๋กœ ์ดˆ๊ธฐํ™” ๋˜์–ด์ง€๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์€ singleton์ด ์ฒ˜์Œ ์‚ฌ์šฉ๋˜์–ด์ง€ ์ „์— ๋งŒ๋“ค์–ด์ง€๊ณ  ์ดˆ๊ธฐํ™”๋จ์œผ๋กœ์„œ ๋ณด์žฅ๋œ๋‹ค.

๋‹ค์Œ์˜ ์˜ˆ๋ฅผ ๋ณด๋ผ. C++ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” Singleton class์˜ Instance operation์„ static member function์œผ๋กœ ์ •์˜ํ•œ๋‹ค. Singleton ๋˜ํ•œ static member ๋ณ€์ˆ˜์ธ _instance๋ฅผ ์ •์˜ํ•œ๋‹ค. _instance๋Š” Singleton์˜ ์œ ์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ์ด๋‹ค.

Singleton class๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ ์–ธ๋œ๋‹ค.
~cpp 
class Singleton {
public:
	static Singleton* Instance ();
protected:
	Singleton ();
private:
	static Singleton* _instance;
};

๋Œ€์‘๋˜๋Š” ์‹ค์ œ ๊ตฌํ˜„๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
~cpp 
Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance () {
	if (_instance == 0) {
		_instance = new Singleton;
	}
	return _instance;
}

ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Client๋Š” singleton์„ Instance operation์„ ํ†ตํ•ด ์ ‘๊ทผํ•œ๋‹ค. _instance ๋Š” 0๋กœ ์ดˆ๊ธฐํ™”๋˜๊ณ , static member function ์ธ Instance๋Š” ๋‹จ์ผ ์ธ์Šคํ„ด์Šค _Instance๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค. ๋งŒ์ผ _instance๊ฐ€ 0์ธ ๊ฒฝ์šฐ unique instance๋กœ ์ดˆ๊ธฐํ™”์‹œํ‚ค๋ฉด์„œ ๋ฆฌํ„ดํ•œ๋‹ค. Instance๋Š” lazy-initalization์„ ์ด์šฉํ•œ๋‹ค. (Instance operation์ด ์ตœ์ดˆ๋กœ ํ˜ธ์ถœ๋˜์–ด์ „๊นŒ์ง€๋Š” ๋ฆฌํ„ดํ•  unique instance๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.)

์ƒ์„ฑ์ž๊ฐ€ protected ์ž„์„ ์ฃผ๋ชฉํ•˜๋ผ. client ๊ฐ€ ์ง์ ‘ Singleton์„ ์ธ์Šคํ„ด์Šคํ™” ํ•˜๋ ค๊ณ  ํ•˜๋ฉด compile-time์‹œ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒˆํ•  ๊ฒƒ์ด๋‹ค. ์ƒ์„ฑ์ž๋ฅผ protected ๋กœ ๋‘ ์œผ๋กœ์„œ ๋Š˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋กœ ๋งŒ๋“ค์–ด์ง€๋„๋ก ๋ณด์ฆํ•ด์ค€๋‹ค.

๋” ๋‚˜์•„๊ฐ€, _instance ๋Š” Singleton ๊ฐ์ฒด์˜ ํฌ์ธํ„ฐ์ด๋ฏ€๋กœ, Instance member function์€ ์ด ํฌ์ธํ„ฐ๋กœ ํ•˜์—ฌ๊ธˆ Singleton ์˜ subclass๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

C++ ๊ตฌํ˜„์— ๋Œ€ํ•ด์„œ๋Š” ์ƒ๊ฐํ•ด์•ผ ํ•  ๊ฒƒ์ด ๋” ์žˆ๋‹ค. singleton ์„ global์ด๋‚˜ static ๊ฐ์ฒด๋กœ ๋‘๊ณ  ๋‚œ ๋’ค ์ž๋™ ์ดˆ๊ธฐํ™”๋˜๋„๋ก ๋†”๋‘๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค. ์ด์— ๋Œ€ํ•ด์„œ๋Š” 3๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ๋‹ค.
  • (a) static ๊ฐ์ฒด์˜ ์œ ์ผํ•œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์„ ์–ธ๋˜์–ด์งˆ ๊ฒƒ์ด๋ผ๊ณ  ๋ณด์žฅํ•  ์ˆ˜ ์—†๋‹ค.
  • (b) ๋ชจ๋“  singleton๋“ค์ด static initialization time ๋Œ€ ์ธ์Šคํ„ด์Šค๋˜๊ธฐ ์œ„ํ•œ ์ถฉ๋ถ„ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„์ˆ˜๋„ ์žˆ๋‹ค. singleton์€ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋  ๋•Œ ๊ทธ๋Ÿฌํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
  • (c) C++ ์€ global ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž๊ฐ€ translation unit๋ฅผ ํ†ตํ•˜๋ฉด์„œ ํ˜ธ์ถœ๋ ๋•Œ์˜ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š๋Š”๋‹คES90. ์ด๋Ÿฌํ•œ ์‚ฌ์‹ค์€ singleton ๋“ค ๊ฐ„์—๋Š” ์–ด๋– ํ•œ ์˜์กด์„ฑ๋„ ์กด์žฌํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•œ๋‹ค. ๋งŒ์ผ ๊ทธ๋Ÿด ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์—๋Ÿฌ๋ฅผ ํ”ผํ•  ์ˆ˜ ์—†๋‹ค.
์•ฝ๊ฐ„ ์ฒจ์–ธ์„ ํ•˜๋ฉด, global/static ๊ฐ์ฒด์˜ ์ ‘๊ทผ์€ singleton๋“ค์ด ์‚ฌ์šฉ๋˜๊ฑด ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฑด ๊ฐ„์— ๋ชจ๋“  singleton์ด ๋งŒ๋“ค์–ด์ง€๋„๋ก ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. static member function ๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๋ฌธ์ œ๋“ค์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.

Smalltalk์—์„œ unique instance๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” functiond์€ Singleton ํด๋ž˜์Šค์˜ class method๋กœ ๊ตฌํ˜„๋œ๋‹ค. ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ new operation์„ overrideํ•œ๋‹ค. The resulting Singleton class might have the following two class methods, where SoleInstance is a class variable that is not used anywhere else:
~cpp 
new
	self error:	'cannot create new object'

default
	SoleInstance isNil ifTrue:  [SoleInstance := super new].
	^ SoleInstance

2. Singleton class๋ฅผ subclassing ํ•˜๊ธฐ ๊ด€๋ จ. ์ฃผ๋œ ์ฃผ์ œ๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ singleton ์˜ subclass๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก subclass๋“ค์˜ unique instance๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ถ€๋ถ„์— ์žˆ๋‹ค. ํ•„์ˆ˜์ ์œผ๋กœ, singleton ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ subclass์˜ ์ธ์Šคํ„ด์Šค๋กœ ์ดˆ๊ธฐํ™”๋˜์–ด์ ธ์•ผ ํ•œ๋‹ค. ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๊ธฐ์ˆ ์€ Singleton์˜ Instance operation์— ์‚ฌ์šฉํ•˜๊ธฐ ์›ํ•˜๋Š” singleton์„ ์ •ํ•ด๋†“๋Š” ๊ฒƒ์ด๋‹ค. Sample Code์—๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋“ค์„ ๊ฐ€์ง€๊ณ  ์ด ๊ธฐ์ˆ ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ๋ณด์—ฌ์ค€๋‹ค.

Singleton์˜ subclass๋ฅผ ์„ ํƒํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ Instance ๋ฅผ Parent class์—์„œ ๋นผ ๋‚ธ๋’ค, (e.g, MazeFactory) subclass ์— Instance๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Š” C++ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋กœ ํ•˜์—ฌ๊ธˆ link-time์‹œ์— singleton์˜ class๋ฅผ ๊ฒฐ์ •ํ•˜๋„๋ก ํ•ด์ค€๋‹ค. (e.g, ๊ฐ๊ฐ ๋‹ค๋ฅธ ๊ตฌํ˜„๋ถ€๋ถ„์„ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒดํ™”์ผ์„ linkingํ•จ์œผ๋กœ์จ.)

์ด๋Ÿฌํ•œ link-approach ๋ฐฉ๋ฒ•์€ link-time๋•Œ singleton class ์˜ ์„ ํƒ์„ ๊ณ ์ •์‹œ์ผœ๋ฒ„๋ฆฌ๋ฏ€๋กœ, run-time์‹œ์˜ singleton class์˜ ์„ ํƒ์„ ํž˜๋“ค๊ฒŒ ํ•œ๋‹ค. subclass๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด๋ฌธ๋“ค (switch-case ๋“ฑ๋“ฑ)์€ ํ”„๋กœ๊ทธ๋žจ์„ ๋” ์œ ์—ฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ทธ๊ฒƒ ๋˜ํ•œ ์ด์šฉ๊ฐ€๋Šฅํ•œ singleton class๋“ค์„ ๋ฌถ์–ด๋ฒ„๋ฆฌ๊ฒŒ ๋œ๋‹ค. ์ด ๋‘๊ฐ€์ง€์˜ ๋ฐฉ๋ฒ• ๋‹ค ๊ทธ๋‹ค์ง€ ์œ ์—ฐํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค.

๋”์šฑ๋” ์œ ์—ฐํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์œผ๋กœ registry of singletons ์ด ์žˆ๋‹ค. ๊ฐ€๋Šฅํ•œ Singleton class๋“ค์˜ ์ง‘ํ•ฉ์„ ์ •์˜ํ•˜๋Š” Instance operation์„ ๊ฐ€์ง€๋Š” ๊ฒƒ ๋Œ€์‹ , Singleton class๋“ค์„ ์ž˜ ์•Œ๋ ค์ง„ registry ์— ๊ทธ๋“ค์˜ singleton instance๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

registry ๋Š” string name ๊ณผ singletons ์„ mapping ํ•œ๋‹ค. singleton์˜ instance๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, registry์— string name์œผ๋กœ ํ•ด๋‹น singleton ์„ ์š”์ฒญํ•œ๋‹ค. registry๋Š” ๋Œ€์‘ํ•˜๋Š” singleton์„ ์ฐพ์•„์„œ (๋งŒ์ผ ์กด์žฌํ•œ๋‹ค๋ฉด) ๋ฆฌํ„ดํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ๋ฐฉ๋ฒ•์€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ Singleton class๋“ค์ด๋‚˜ instance๋“ค์„ Instance operation์ด ์•Œ ํ•„์š”๊ฐ€ ์—†๋„๋ก ํ•œ๋‹ค. ํ•„์š”ํ•œ ๊ฒƒ์€ registry์— ๋“ฑ๋ก๋  ๋ชจ๋“  Singleton class๋“ค์„ ์œ„ํ•œ ์ผ๋ฐ˜์ ์ธ interface์ด๋‹ค.
~cpp 
class Singleton {
public:
	static void Register (const char* name, Singleton*);
	static Singleton* Instance ();
protected:
	static Singleton* Lookup (const char* name);
private:
	static Singleton* _instance;
	static List<NameSingletonPair>* _registry;
};

Register operation์€ ์ฃผ์–ด์ง„ string name์œผ๋กœ Singleton instance๋ฅผ ๋“ฑ๋กํ•œ๋‹ค. registry๋ฅผ ๋‹จ์ˆœํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” NameSingletonPair ๊ฐ์ฒด์˜ ๋ฆฌ์ŠคํŠธ์— instance๋ฅผ ์ €์žฅํ•  ๊ฒƒ์ด๋‹ค. ๊ฐ NameSingletonPair๋Š” name๊ณผ instance๋ฅผ mappingํ•œ๋‹ค. Lookup operation์€ ์ฃผ์–ด์ง„ ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  singleton์„ ์ฐพ๋Š”๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์˜ ์ฝ”๋“œ์—์„œ environment variable์ด ์›ํ•˜๋Š” singleton์˜ ์ด๋ฆ„์„ ๋ช…์‹œํ•˜๊ณ  ์žˆ์Œ์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
~cpp 
Singleton* Singleton::Instance () {
	if (_instance == 0) {
		const char* singletonName = getenv("SINGLETON");
		// user or environment supplies this at startup

		_instance = Lookup (singletonName);
		// Lookup returns 0 if there's no such singleton
	}
	return _instance;
}
์–ด๋””์—์„œ Singleton class๋“ค์ด ๊ทธ๋“ค์„ ๋“ฑ๋กํ•˜๋Š”๊ฐ€? ํ•œ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ์€ ๊ทธ๋“ค์˜ ์ƒ์„ฑ์ž์—์„œ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด singleton์˜ subclass์ธ MySingleton ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
~cpp 
MySingleton::MySingleton () {
	// ...
	Singleton::Register ("MySingleton", this);
}
๋ฌผ๋ก , ์ฝ”๋“œ ์–ด๋””์—์„ ๊ฐ€ ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒ์„ฑ์ž๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. C++์—์„œ๋Š” MySingleton์˜ static instance๋ฅผ ์ •์˜ํ•จ์œผ๋กœ์„œ ์ด ๋ฌธ์ œ๋ฅผ ์ž˜ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, MySingleton ํด๋ž˜์Šค์˜ ๊ตฌํ˜„๋ถ€๋ฅผ ํฌํ•จํ•˜๋Š” ํ™”์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.
~cpp 
static MySingleton theSingleton;

๋” ์ด์ƒ Singleton class ๋Š” singleton ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ฑ…์ž„์ด ์—†๋‹ค. ๊ทธ ๋Œ€์‹  ์ด์ œ Singleton ์˜ ์ฃผ๋œ ์ฑ…์ž„์€ ์‹œ์Šคํ…œ ๋‚ด์—์„œ ์„ ํƒํ•œ singleton ๊ฐ์ฒด๋ฅผ ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. static object approach๋Š” ์—ฌ์ „ํžˆ ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค. ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ Singleton subclass๋“ค์˜ ์ธ์Šคํ„ด์Šค๋“ค์ด ์ƒ์„ฑ๋˜์–ด์ง€๋˜์ง€, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด register๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

1.9. Sample Code

๋ฏธ๋กœ๋ฅผ ๋งŒ๋“œ๋Š” MazeFactory ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ–ˆ๋‹ค๊ณ  ํ•˜์ž. MazeFactory ๋Š” ๋ฏธ๋กœ์˜ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ถ€๋ถ„๋“ค์„ ๋งŒ๋“œ๋Š” interface๋ฅผ ์ •์˜ํ•œ๋‹ค. subclass๋“ค์€ ๋” ํŠน๋ณ„ํ™”๋œ product class๋“ค์˜ instance๋“ค์„ ๋ฆฌํ„ดํ•˜๊ธฐ ์œ„ํ•œ opeation๋“ค์„ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด BombedWall ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜์ ์ธ Wall๊ฐ์ฒด๋ฅผ ๋Œ€์‹ ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ SingletonPattern๊ณผ ๊ด€๋ จ ๋˜๋Š” ๋‚ด์šฉ์€ Maze application์€ ๋‹จ ํ•˜๋‚˜์˜ maze factory๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค๋Š” ๊ฒƒ๊ณผ ๊ทธ maze factory์˜ ์ธ์Šคํ„ด์Šค๋Š” ์–ด๋””์„œ๋“ ์ง€ maze์˜ ๋ถ€๋ถ„์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฌํ•  ๋•Œ๊ฐ€ ๋ฐ”๋กœ SingletonPattern์„ ๋„์ž…ํ•  ๋•Œ์ด๋‹ค. MazeFactory๋ฅผ Singleton์œผ๋กœ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ, global variable์— ๋Œ€ํ•œ ์žฌ์ •๋ ฌ์„ ํ•  ํ•„์š”๊ฐ€ ์—†์ด maze ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋•Œ ํ•„์š”ํ•œ MazeFactory๋ฅผ globalํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

์ผ๋‹จ ๋‹จ์ˆœํ•˜๊ฒŒ, MazeFactory์˜ subclassing์ด ํ•„์š”์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. (์ž ์‹œ ํ›„ subclassing๊ณผ ๊ด€๋ จ, ๋Œ€์•ˆ์ ์ธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ณ ๋ คํ•ด ๋ณผ ๊ฒƒ์ด๋‹ค.) C++ ์—์„œ๋Š” static operation์ธ Instance์™€ unique instance๋ฅผ ์ฐธ์กฐํ•˜๋Š” static member์ธ _instance ๋ฅผ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์„œ Singleton ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„์˜ Implementation์—์„œ๋„ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋ฐ˜๋“œ์‹œ ์ƒ์„ฑ์ž๋Š” protected๋กœ ๋‘ ์œผ๋กœ์„œ ์šฐ๋ฐœ์ ์œผ๋กœ ํ•˜๋‚˜์ด์ƒ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค.

~cpp 
class MazeFactory {
	public:
		static MazFactory* Instance ();

		// existing interface goes here
	protected:
		MazeFactory ();
	private:
		static MazeFactory* _instance;
	};

๋Œ€์‘๋˜๋Š” ํด๋ž˜์Šค์˜ ์‹ค์ œ ๊ตฌํ˜„๋ถ€๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

~cpp 
MazeFactory* MazeFactory::_instance = 0;

MazeFactory* MazeFactory::Instance () {
	if (_instance == 0) {
		_instance = new MazeFactory;
	}

	return _instance;
}

์ž, ์ด์ œ MazeFactory์˜ subclassing์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณด์ž. MazeFactory์˜ subclass๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ, application์€ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉํ•  singleton์„ ๊ฒฐ์ •ํ•ด์•ผ ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด maze์˜ ์ข…๋ฅ˜๋ฅผ ์„ ํƒํ•˜๊ณ , ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ’์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ์ ํ•ฉํ•œ MazeFactory subclass๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ง๋ถ™์ผ ๊ฒƒ์ด๋‹ค. Instance operation์€ ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ์ข‹์€ ์žฅ์†Œ์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด Instance operation์€ MazeFactory๋ฅผ ์ธ์Šคํ„ด์Šคํ•˜๋Š” operation์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
~cpp 
MazeFactory* MazeFactory::Instance () {
	if (_instance == 0) {
		const char* mazeStyle = getenv ("MAZESTYLE");

		if (strcmp (mazeStyle, "bombed") == 0) {
			_instance = new BombedMazeFactory;

		} else if (strcmp (mazeStyle, "enchanted") == 0) {
			_instance = new EnchantedMazeFactory;
		

		// ... other possible subclasses

		} else {		// default
			_instance = new MazeFactory;
		}
	}

	return _instance;
}
์ƒˆ๋กœ์šด MazeFactory์˜ subclass๋ฅผ ์ •์˜ํ• ๋•Œ ๋งค๋ฒˆ Instance ๊ฐ€ ๋ฐ˜๋“œ์‹œ ์ˆ˜์ •๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ๋ชฉํ•˜์ž. ์ด application์—์„œ์•ผ ๋ณ„๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒ ์ง€๋งŒ, ์ด๋Ÿฌํ•œ ๊ตฌํ˜„์€ framework ๋‚ด์— ์ •์˜๋œ abstract factory๋“ค ๋‚ด์—์„œ๋งŒ ํ•œ์ •๋˜์–ด๋ฒ„๋ฆฐ๋‹ค. (Implementation์˜ subclass ๊ด€๋ จ ๋ถ€๋ถ„ ์ฐธ์กฐ)

๊ฐ€๋Šฅํ•œ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ๋Š” Implementation์—์„œ ์–ธ๊ธ‰ํ•œ registry approach๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Dynamic linking ๋ฐฉ๋ฒ•๋„ ๋˜ํ•œ ์œ ์šฉํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. Dynamic linking ์€ application์œผ๋กœ ํ•˜์—ฌ๊ธˆ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” subclass ๋„ ์ „๋ถ€ loadํ•ด์•ผ ํ•  ํ•„์š”์„ฑ์„ ๋œ์–ด์ค€๋‹ค.

1.10. Known Uses

Smalltalk-80Par90 ์˜ SingletonPattern์˜ ์˜ˆ๋Š” ChangeSet current๋ผ๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•œ change๋“ค ์ง‘ํ•ฉ๋“ค์ด๋‹ค. ๋” ์ ํ•ฉํ•œ ์˜ˆ์ œ๋กœ๋Š” ํด๋ž˜์Šค๋“ค๊ณผ ๊ทธ๋“ค์˜ metaclass ๊ฐ„์˜ ๊ด€๊ณ„์ด๋‹ค. metaclass๋Š” ํด๋ž˜์Šค์˜ ํด๋ž˜์Šค๋กœ, ๊ฐ metaclass๋Š” ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง„๋‹ค. metaclass๋“ค์€ ์ด๋ฆ„์„ ๊ฐ€์ง€์ง€ ์•Š์ง€๋งŒ (๊ทธ๋“ค์˜ ๋‹จ์ผ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•œ ๊ฐ„์ ‘์ ์ธ ๋ฐฉ๋ฒ•์„ ใ…”ใ…šํ•˜๊ณ ), ๊ทธ๋“ค์˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ์— ์˜ํ•ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

InterViews user interface toolkitLCI+92๋Š” toolkit์˜ Session๊ณผ WidgetKit ํด๋ž˜์Šค์˜ unique instance์— ์ ‘๊ทผํ•˜์ง€ ์œ„ํ•ด SingletonPattern์„ ์ด์šฉํ•œ๋‹ค. Session์€ application์˜ ๋ฉ”์ธ ์ด๋ฒคํŠธ๋ฅผ dispatchํ•˜๋Š” ๋ฃจํ”„๋ฅผ ์ •์˜ํ•˜๊ณ  ์‚ฌ์šฉ์ž ์Šคํƒ€์ผ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ €์žฅํ•˜๊ณ , ํ•˜๋‚˜๋‚˜ ๊ทธ ์ด์ƒ์˜ ๋ฌผ๋ฆฌ์  display ์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ๋“ค(connections)์„ ๊ด€๋ฆฌํ•œ๋‹ค. WidgetKit์€ user interface widgets์˜ look and feel์„ ์ •์˜ํ•œ๋‹ค. WidgetKit::instance () operation์€ Session ์—์„œ ์ •์˜๋œ ํ™˜๊ฒฝ๋ณ€์ˆ˜์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ํŠน์ • WidgetKit ์˜ subclass๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. Session์˜ ๋น„์Šทํ•œ operation์€ ์ง€์›ํ•˜๋Š” display๊ฐ€ monochrome display์ธ์ง€ color display์ธ์ง€ ๊ฒฐ์ •ํ•˜๊ณ  ์ด์— ๋”ฐ๋ผ์„œ singleton ์ธ Session instance๋ฅผ ์„ค์ •ํ•œ๋‹ค.

1.11. Related Patterns

๋งŽ์€ pattern๋“ค์ด SingletonPattern์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋‹ค. AbstractFactoryPattern, BuilderPattern, PrototypePattern์„ ์ฐธ์กฐํ•˜๋ผ.



์งˆ๋ฌธ
  • ์ œ๊ฐ€ ํ…Œ์ŠคํŠธ ์šฉ์œผ๋กœ n-class singleton์„ ๊ตฌํ˜„ํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•ด์•ผ ๋ ๊นŒ์š”?

~cpp 
----- CNSingleton.h ------

#include <afxtempl.h>

class CNSingleton : public CObject  
{
public:
         class CSingletonList; //  C2248 ํ•ด๊ฒฐ
         friend CSingletonList; //  C2248 ํ•ด๊ฒฐ 
	static CNSingleton* Instance();

private:
	CNSingleton();	
	virtual ~CNSingleton();

	////////////////////////////////////////////
	// inner class
	static class CSingletonList : public CObject
	{
	public:
		CSingletonList() throw();
		virtual ~CSingletonList() throw();

		CNSingleton* Next();

	private:
		void Init();
		void Destory();

		int m_Count;
		int m_Index;
		CList <CNSingleton*, CNSingleton*>* m_ContainerOfSingleton;
	};

	static CSingletonList* m_Instances;
};

----- CNSingleton.cpp ------

#include "stdafx.h"
#include "NSingleton.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNSingleton::CSingletonList::CSingletonList() throw()
{
	Init();
}

CNSingleton::CSingletonList::~CSingletonList() throw()
{
	Destory();
	delete m_ContainerOfSingleton;
}

////////////////////////////////////////////////////////////////////////
// ๊ฐ์ฒด ์ดˆ๊ธฐํ™”
void CNSingleton::CSingletonList::Init()
{
	m_Index = 0;
	m_Count = 3;//์ž„์‹œ
	m_ContainerOfSingleton = new CList <CNSingleton*, CNSingleton*>;
	for (int i = 0; i < m_Count; i++)
	{
		m_ContainerOfSingleton->AddTail(new CNSingleton());
	}
}

////////////////////////////////////////////////////////////////////////
// ๊ฐ์ฒด destory
void CNSingleton::CSingletonList::Destory()
{
	POSITION position = m_ContainerOfSingleton->GetHeadPosition();
	while(position)
	{
		delete m_ContainerOfSingleton->GetAt(position);
		m_ContainerOfSingleton->GetNext(position);
	}

	m_ContainerOfSingleton->RemoveAll();
}

////////////////////////////////////////////////////////////////////////
// index์— ํ•ด๋‹นํ•˜๋Š” CNSingleton๋ฅผ Container์—์„œ ์ฐพ์•„ ๋ฐ˜ํ™˜ 
CNSingleton* CNSingleton::CSingletonList::Next()
{
	if (m_Index == m_ContainerOfSingleton->GetCount())
		m_Index = 0;

	POSITION position = m_ContainerOfSingleton->FindIndex(m_Index);
	m_Index++;

	return m_ContainerOfSingleton->GetAt(position);
}



//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNSingleton::CSingletonList* CNSingleton::m_Instances = NULL;
CNSingleton::CNSingleton()
{
	m_Instances = new CSingletonList();
}

CNSingleton::~CNSingleton()
{
	delete m_Instances;
}

////////////////////////////////////////////////////////////////////////
// n-th instance๋ฅผ ์–ป์–ด์˜จ๋‹ค.
CNSingleton* CNSingleton::Instance()
{
	return m_Instances->Next();
}

์ด ์†Œ์Šค๋ฅผ ์ปดํŒŒ์ผํ•˜๋ฉด, outer class์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„, ์ฆ‰ Init()๊ณผ Destroy()์—์„œ
error C2248: 'CNSingleton::CNSingleton' : cannot access private member declared in class 'CNSingleton' ๋ผ๊ณ  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
inner class์—์„œ๋Š” outer class์˜ private ์ƒ์„ฑ์ž์— ์ ‘๊ทผํ•  ๊ถŒํ•œ์ด ์—†๋‚˜์š”?
๋งŒ์•ฝ ์ € ์ฝ”๋“œ๋ฅผ ์ œ๋Œ€๋กœ ์ˆ˜์ •ํ•˜๋ ค ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ๋˜๋‚˜์š”? ์ฐธ๊ณ ๋กœ ์ €๋Š” http://www.javaworld.com/javaworld/javaqa/2001-11/01-qa-1102-singleton.html์— ์žˆ๋Š” ์ž๋ฐ”์†Œ์Šค๋ฅผ cpp๋กœ ํฌํŒ…ํ–ˆ์Šต๋‹ˆ๋‹ค. -- FredFrith

์ œ๊ฐ€ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ ๋‘์ค„
~cpp 
         class CSingletonList; //  C2248 ํ•ด๊ฒฐ
         friend CSingletonList; //  C2248 ํ•ด๊ฒฐ 
์„ ๋ณด์‹ญ์‹œ์˜ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -- imays
DeleteMe) imays ์ด๋ฉด, ํ˜น์‹œ ํ˜„์ง์ดํ˜•์ด์‹ ๊ฐ€์š”? --๊ธฐ์–ต์„ ํ•˜์‹ค์ง€ ๋ชจ๋ฅด๊ฒ ๋Š” 1002 -- ๋„ต imays
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:19
Processing time 0.0131 sec