์ž์› ๊ด€๋ฆฌ
NHN NEXT ์žฅ๋ฌธ์ต
resource
๏‚š ์‚ฌ์šฉ์„ ์ผ๋‹จ ๋งˆ์น˜๊ณ  ๋‚œ ํ›„์—” ์‹œ์Šคํ…œ์— ๋Œ๋ ค์ฃผ์–ด์•ผ ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ
๏‚š ๊ฐ€์ ธ์™€์„œ ๋‹ค ์ป์œผ๋ฉด ํ•ด์ œํ•ด์•ผ, ์ฆ‰ ๋†“์•„ ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
๏‚š ๋™์  ํ• ๋‹น ๋ฉ”๋ชจ๋ฆฌ(๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ ์„œ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉด memory leak)
์ž์›์„ ํ•ญ์ƒ ํ•ด์ œ๋˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•
๏‚š ์ž์›์„ ๊ฐ์ฒด์— ๋„ฃ๊ณ 
๏‚š ๊ทธ ์ž์› ํ•ด์ œ๋ฅผ ์†Œ๋ฉธ์ž๊ฐ€ ๋งก๋„๋ก ํ•˜๋ฉฐ,
๏‚š ๊ทธ ์†Œ๋ฉธ์ž๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ๋˜๋„๋ก ๋งŒ๋“ ๋‹ค.
auto_ptr
๏‚š ํฌ์ธํ„ฐ์™€ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฐ์ฒด(smart
pointer)
๏‚š ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋Œ€์ƒ์— ๋Œ€ํ•ด ์†Œ๋ฉธ์ž๊ฐ€ ์ž๋™์œผ
๋กœ delete๋ฅผ ๋ถˆ๋Ÿฌ์ฃผ๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ๋‹ค.
๏‚š ํ•œ ๊ฐ์ฒด๋ฅผ ๋™์‹œ์— ๋‘˜์ด ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์—†๋‹ค. ๋ณต์‚ฌ์ƒ
์„ฑํ•˜๊ฑฐ๋‚˜ ๋Œ€์ž…ํ•˜๋ฉด ํ•œ auto_ptr์€ null์ด ๋œ๋‹ค.
std::auto_ptr<Investment>(createInvestment
());
์ž์› ๊ด€๋ฆฌ์— ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•1
๏‚š ์ž์›์„ ํš๋“ํ•œ ํ›„์— ์ž์› ๊ด€๋ฆฌ ๊ฐ์ฒด์— ๋„˜๊ธด๋‹ค.
๏‚š ์ž์› ํš๋“ ์ฆ‰ ์ดˆ๊ธฐํ™”(Resource Acquisition is Initialization:RAII)
๏‚š ์ž์› ํš๋“๊ณผ ์ž์› ๊ด€๋ฆฌ ๊ฐ์ฒด์˜ ์ดˆ๊ธฐํ™”๊ฐ€ ํ•œ ๋ฌธ์žฅ์—์„œ ์ด๋ฃจ์–ด ์ง„๋‹ค.
์ž์› ๊ด€๋ฆฌ์— ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•2
๏‚š ์ž์› ๊ด€๋ฆฌ ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ์†Œ๋ฉธ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž์›์ด ํ™•์‹คํžˆ ํ•ด์ œ๋˜๋„๋ก ํ•œ๋‹ค.
๏‚š ์†Œ๋ฉธ์ž๋Š” ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ ์ž๋™์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ์‹คํ–‰ ์ œ์–ด๊ฐ€ ์–ด๋–ค ๊ฒฝ์œ„๋กœ ๋ธ”๋ก์„ ๋– ๋‚˜๋Š”๊ฐ€
์— ์ƒ๊ด€์—†์ด ์ž์› ํ•ด์ œ๊ฐ€ ์ œ๋Œ€๋กœ ์ด๋ฃจ์–ด์ง€๊ฒŒ ๋œ๋‹ค.
auto_ptr์˜ ํŠน์„ฑ
std::auto_ptr<Investment>pInv1(creteInvestment());
std::auto_ptr<Investment>pInv2(pInv1); // pInv2๊ฐ€ ๊ฐ€๋ฆฌ์ง€๋Š” ๊ฐ์ฒด๋Š” pInv1์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด
// pInv1์€ null, auto_ptr์˜ ํŠน์„ฑ
pInv1 = pInv2 // pInv1๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ , pInv2๋Š” null
auto_ptr๊ฐ€ ๋‹ต์ธ๊ฐ€?
๏‚š ๋ณต์‚ฌ ๋™์ž‘์ด ์ด๋ฃจ์–ด์ง€๋ฉด ์ด์ „์˜ ๊ฒƒ์€ null์ด ๋œ๋‹ค.
๏‚š auto_ptr๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๋Š” ๋‘๊ฐœ ์ด์ƒ์˜ auto_ptr๊ฐ€ ๋ฌผ๊ณ  ์žˆ์œผ๋ฉด ์•ˆ ๋œ๋‹ค.
๏‚š ์ด ๋‘ ๊ฐ€์ง€ ํŠน์„ฑ๋•Œ๋ฌธ์— ๋™์ ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ๋ชจ๋“  ์ž์›์— ๋Œ€ํ•œ ๊ด€๋ฆฌ ๊ฐ์ฒด๋กœ์„œ auto_ptr๋ฅผ ์“ฐ๋Š” ๊ฒƒ์€
์ตœ์„ ์ด ์•„๋‹Œ ๋“ฏํ•˜๋‹ค.
์ฐธ์กฐ ์นด์šดํŒ… ๋ฐฉ์‹ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ
๏‚š reference-counting smart pointer(RCSP)
๏‚š ํŠน์ •ํ•œ ์–ด๋–ค ์ž์›์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์™ธ๋ถ€ ๊ฐ์ฒด์˜ ๊ฐœ
์ˆ˜๋ฅผ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ๊ทธ ๊ฐœ์ˆ˜๊ฐ€ 0์ด ๋˜๋ฉด ํ•ด
๋‹น ์ž์›์œผ๋กœ ์‚ญ์ œํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ
๏‚š garbage collection ๋ฐฉ์‹๊ณผ ์œ ์‚ฌ
๏‚š std::tr1::shared_ptr<Investment>pInv(crea
teInvestment());
reference-counting smart pointer์˜ ํŠน์„ฑ
std::tr1::shared_ptr<Investment>pInv1(createInvestment());
std::tr1::shared_ptr<Investment>pInv1(pInv2); // auto_ptr๊ณผ ๋‹ฌ๋ฆฌ pInv1, pInv2๊ฐ€
// ๋™์‹œ์— ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
pInv1 = pInv2; // ๋ณ€ํ™”์—†์Œ
auto_ptr, tr1::shared_ptr์˜ ๊ณตํ†ต ํŠน์„ฑ
๏‚š ์†Œ๋ฉธ์ž ๋‚ด๋ถ€์—์„œ delete ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
๏‚š delete [] ์—ฐ์‚ฐ์ž๊ฐ€ ์•„๋‹ˆ๋‹ค.
๏‚š ์ฆ‰, ๋™์  ํ• ๋‹นํ•œ ๋ฐฐ์—ด์— auto_ptr, tr1::shared_ptr์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.
std::auto_ptr<std::string>aps(new std::string[10]); // error
std::tr1::shared_ptr<int> spi(new int[1024]);; // error
RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋  ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜?
๏‚š ๋ณต์‚ฌ๋ฅผ ๊ธˆ์ง€ํ•œ๋‹ค.
class Lock : private Uncopyable {
public :
โ€ฆ
};
RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋  ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜?
๏‚š ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์ž์›์— ๋Œ€ํ•ด ์ฐธ์กฐ ์นด์šดํŒ…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
๏‚š ์ž์›์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋งˆ์ง€๋ง‰ ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ๊นŒ์ง€ ๊ทธ ์ž์›์„ ํ•ด์ œํ•˜๋ฉด ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ
๏‚š tr1::shared_ptr๋ฅผ ์ด์šฉ?
๏‚š tr1::shared_ptr๋ฅผ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋  ๋•Œ ์ž์‹ ์ด ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋˜ ๋Œ€์ƒ์„ ์‚ญ์ œํ•˜๋„๋ก ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ
์— ์•ˆ ๋œ๋‹ค.
๏‚š tr1:shared_ptr๋Š” โ€ž์‚ญ์ œ์ž(delete)โ€Ÿ ์ง€์ •์„ ํ—ˆ์šฉํ•œ๋‹ค.
shared_ptr ์‚ญ์ œ์ž ํ™œ์šฉ
class Lock {
public :
explicit Lock(Mutex *pm) // shared_ptr๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š”๋ฐ, ๊ฐ€๋ฆฌํ‚ฌ ํฌ์ธํ„ฐ๋กœ
: mutexPtr(pm, unlock // Mutex ๊ฐ์ฒด์˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‚ญ์ œ์ž๋กœ unlock ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ
{
lock(mutexPtr.get());
)
private :
std::tr1::shared_ptr<Mutex>mutexPtr;
}
RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋  ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜?
๏‚š ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์ž์›์„ ์ง„์งœ๋กœ ๋ณต์‚ฌํ•œ๋‹ค.
๏‚š ๊นŠ์€ ๋ณต์‚ฌ(deep copy)
RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋  ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜?
๏‚š ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์ž์›์˜ ์†Œ์œ ๊ถŒ์„ ์˜ฎ๊ธด๋‹ค.
๋ช…์‹œ์  ๋ณ€ํ™˜(explicit conversion)
๏‚š tr1::shared_ptr ๋ฐ auto_ptr์€ ๋ช…์‹œ์  ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” get์ด๋ผ๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
๏‚š get ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“  ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๊ฐ์ฒด์— ๋“ค์–ด์žˆ๋Š” ์‹ค์ œ ํฌ์ธํ„ฐ๋ฅผ ์–ป์–ด๋‚ธ๋‹ค.
std::tr1::shared_ptr<Investment> pInv(createInvestment());
int daysHeld(const Investment *pi);
// int days = daysHeld(pInv); // error
int days = daysHeld(pInv.get());
์ž์› ์ ‘๊ทผ๊ณผ ๋ช…์‹œ์ , ์•”์‹œ์  ๋ณ€ํ™˜
๏‚š ์•ˆ์ „์„ฑ๋งŒ ๋”ฐ์ง€๋งŒ ๋ช…์‹œ์  ๋ณ€ํ™˜์ด ๋Œ€์ฒด์ ์œผ๋กœ ๋‚ซ๋‹ค.
๏‚š ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž ํŽธ์˜์„ฑ์„ ๋†“๊ณ  ๋ณด๋ฉด ์•”์‹œ์  ๋ณ€ํ™˜์ด ๊ดœ์ฐฎ๋‹ค.
๏‚š โ€œ๋งž๊ฒŒ ์“ฐ๊ธฐ์—๋Š” ์‰ฝ๊ฒŒ, ํ‹€๋ฆฌ๊ฒŒ ์“ฐ๊ธฐ์—๋Š” ์–ด๋ ต๊ฒŒโ€œ
new
๏‚š ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ๋‹ค.
๏‚š ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•ด ํ•œ ๊ฐœ ์ด์ƒ์˜ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
delete
๏‚š ๊ธฐ์กด์— ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•ด ํ•œ ๊ฐœ ์ด์ƒ์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
๏‚š ๊ทธ ํ›„์— ๊ทธ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋œ๋‹ค.
๊ฐ์ฒด ๋ฐฐ์—ด delete
st::string *stringPtr1 = new std::string;
st::string *stringPtr1 = new std::string[100];
โ€ฆ
delete stringPtr1;
delete [] stringPtr2;
typedef std::string AddressLines[4];
std::string *pal = new AddressLines
// delete pal;
delete [] pal;
new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋กœโ€ฆ
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
// processWidget(new Widget, priority()); error!
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
std::tr1::shared_ptr์˜ ์ƒ์„ฑ์ž๋Š” explicit๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— โ€žnew Widgetโ€Ÿํ‘œํ˜„์‹์— ์˜ํ•ด ๋งŒ๋“ค์–ด
์ง„ ํฌ์ธํ„ฐ๊ฐ€ tr1::shared_ptr ํƒ€์ž…์˜ ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๋Š” ์•”์‹œ์ ์ธ ๋ณ€ํ™˜์ด ์—†๋‹ค.
๋งค๊ฐœ๋ณ€์ˆ˜ ํ˜ธ์ถœ ์ˆœ์„œ์— ๋”ฐ๋ฅธ ์œ„ํ—˜์„ฑ
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
์—ฐ์‚ฐ์ด ์‹คํ–‰๋˜๋Š” ์ˆœ์„œ
priority -> โ€œnew Widgetโ€ -> tr1::shared_ptr?
๋ฐ˜๋“œ์‹œ ์œ„์˜ ์ˆœ์„œ๋Œ€๋กœ ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.
priority๊ฐ€ ๋ช‡ ๋ฒˆ์งธ๋กœ ํ˜ธ์ถœ๋ ์ง€๋Š” ๋ชจ๋ฅธ๋‹ค.
๋ฌธ์ œ๋Š” priority ํ˜ธ์ถœ๋ถ€๋ถ„์—์„œ error๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด โ€œnew Widgetโ€์œผ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ํฌ์ธํ„ฐ๊ฐ€ ์œ ์‹ค๋  ์ˆ˜ ์žˆ๋‹ค.
ํ•ด๊ฒฐ์ฑ…
std::tr1::shared_ptr<Widget> pw(new widget); // new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์—
processWidget(pw, priority()); // prority ํ˜ธ์ถœ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ํฌ์ธํ„ฐ ์œ ์‹ค ์—†์Œ
// memory leak ๋ฐฉ์ง€
๊ทธ๋ž˜์„œ new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋กœ ๋„ฃ๋Š” ์ฝ”๋“œ๋Š” ๋ณ„๋„์˜ ํ•œ ๋ฌธ์žฅ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
์„ค๊ณ„ ๋ฐ ์„ ์–ธ
์ œ๋Œ€๋กœ ์“ฐ๊ธฐ ์‰ฝ๊ฒŒ, ์—‰ํ„ฐ๋ฆฌ๋กœ ์“ฐ๊ธฐ ์–ด๋ ต๊ฒŒ
class Date {
public :
Date(int month, int day, int year);
โ€ฆ
};
Date d(30, 3, 1995); // ์›”, ์ผ์ด ๋ฐ”๋€œ
Date d(3, 40, 1955); // ์ผ์ด ์ด์ƒํ•œ ๊ฐ’
struct Day {
explicit Day(int d) : val (d) {}
int val;
};
class Date {
public:
Date(const Month& m, const Day& d,
const Year& y);
โ€ฆ
};
Date d(30, 3, 1955) // ์ž๋ฃŒํ˜•์ด ํ‹€๋ ธ๋‹ค.
Date d(Day(30), Month(3), Year(1995));
// ์ž๋ฃŒํ˜•์ด ํ‹€๋ ธ๋‹ค.
Date d(Month(3), Day(30), Year(1995));
Investment * createInvestment();
std::tr1::shared_ptr<Investment>createInvestment();
๋ฐ˜ํ™˜๊ฐ’์ด shared_ptr์ด๋ผ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉ์ž๊ฐ€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
์ด ๊ฐ์ฒด๋ฅผ ์‚ญ์ฒดํ•˜๋Š” ๊ฒƒ์„ ๊นœ๋นกํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋”๋ผ๋„ share_ptr๊ฐ€ ์•Œ์•„์„œ ํ•ด์ œํ•œ๋‹ค.
tr1::shared_ptr์˜ ํŠน์„ฑ ์ด์šฉ1
๏‚š ์ƒ์„ฑ ์‹œ์ ์— ์ž์› ํ•ด์ œ ํ•จ์ˆ˜(โ€ž์‚ญ์ œ์žโ€ž)๋ฅผ ์—ฎ์„ ์ˆ˜ ์žˆ๋‹ค.
std::tr1::shared_ptr<Investment>pInv(0, getRidOfInvestment); // error
std::tr1::shared_ptr<Investment*>pInv(static_cast<Investment*>)(0), getRidOfInvestmentl
// 0์€ int, tr1::share_ptr๊ฐ€ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ Investmet* ํƒ€์ž…์˜ ์‹ค์ œ ํฌ์ธํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— static_cast
tr1::shared_ptr์˜ ํŠน์„ฑ ์ด์šฉ2
๏‚š ๊ต์ฐจ DLL ๋ฌธ์ œ ํ•ด๊ฒฐ
๏‚š ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ์— ์–ด๋–ค ๋™์  ๋งํฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ new๋ฅผ ์ผ๋Š”๋ฐ ๊ทธ ๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ•  ๋•Œ๋Š” ์ด์ „์˜ DLL๊ณผ
๋‹ค๋ฅธ DLL์— ์žˆ๋Š” delete๋ฅผ ์„ฐ์„ ๊ฒฝ์šฐ
๏‚š tr1::shared_ptr์˜ ๊ธฐ๋ณธ ์‚ญ์ œ์ž๋Š” tr1::shared_ptr์ด ์ƒ์„ฑ๋œ DLL๊ณผ ๋™์ผํ•œ DLL์—์„œ delete๋ฅผ ์‚ฌ์šฉํ•˜
๋„๋ก ๋งŒ๋“ค์–ด์ ธ ์žˆ๋‹ค.
์ข‹์€ ํด๋ž˜์Šค ์„ค๊ณ„
๏‚š ์ƒˆ๋กœ ์ •์˜ํ•œ ํƒ€์ž…์˜ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์†Œ๋ฉธ์€ ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•˜๋Š”๊ฐ€?
๏‚š ๊ฐ์ฒด ์ดˆ๊ธฐํ™”๋Š” ๊ฐ์ฒด ๋Œ€์ž…๊ณผ ์–ด๋–ป๊ฒŒ ๋‹ฌ๋ผ์•ผ ํ•˜๋Š”๊ฐ€?
๏‚š ์ƒˆ๋กœ์šด ํƒ€์ž…์œผ๋กœ ๋งŒ๋“  ๊ฐ์ฒด๊ฐ€ ๊ฐ’์— ์˜ํ•ด ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ์— ์–ด๋–ค ์˜๋ฏธ๋ฅผ ์ค„ ๊ฒƒ์ธ๊ฐ€?
๏‚š ์ƒˆ๋กœ์šด ํƒ€์ž…์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ ๋ฒ•ํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ œ์•ฝ์€ ๋ฌด์—‡์œผ๋กœ ์žก์„ ๊ฒƒ์ธ๊ฐ€?
๏‚š ๊ธฐ์กด์˜ ํด๋ž˜์Šค ์ƒ์† ๊ณ„ํ†ต๋ง์— ๋งž์ถœ ๊ฒƒ์ธ๊ฐ€?
๏‚š ์–ด๋–ค ์ข…๋ฅ˜์˜ ํƒ€์ž… ๋ณ€ํ™˜์„ ํ—ˆ์šฉํ•  ๊ฒƒ์ธ๊ฐ€? (implicity, explicit)
๏‚š ์–ด๋–ค ์—ฐ์‚ฐ์ž์™€ ํ•จ์ˆ˜๋ฅผ ๋‘์–ด์•ผ ์˜๋ฏธ๊ฐ€ ์žˆ์„๊นŒ?
์ข‹์€ ํด๋ž˜์Šค ์„ค๊ณ„
๏‚š ํ‘œ์ค€ ํ•จ์ˆ˜๋“ค ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ํ—ˆ์šฉํ•˜์ง€ ๋ง ๊ฒƒ์ธ๊ฐ€?
๏‚š ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ๋ฉค๋ฒ„์— ๋Œ€ํ•œ ์ ‘๊ทผ๊ถŒํ•œ์€ ์–ด๋А ์ชฝ์— ์ค„ ๊ฒƒ์ธ๊ฐ€?
๏‚š โ€ž์„ ์–ธ๋˜์ง€ ์•Š์€ ์ธํ„ฐํŽ˜์ด์Šคโ€Ÿ๋กœ ๋ฌด์—‡์„ ๋‘˜ ๊ฒƒ์ธ๊ฐ€?
๏‚š ์ƒˆ๋กœ ๋งŒ๋“œ๋Š” ํƒ€์ž…์ด ์–ผ๋งˆ๋‚˜ ์ผ๋ฐ˜์ ์ธ๊ฐ€?
๏‚š ์ •๋ง๋กœ ํ•„์š”ํ•œ ํƒ€์ž…์ธ๊ฐ€?
pass_by_value?
class Person {
public :
Person();
virtual ~ Person();
โ€ฆ
private :
std::string name;
std::string address;
};
class Student : public Person {
public :
Student();
~Student();
โ€ฆ
private:
std::string schoolName;
std::string schoolAddress;
};
pass-by-value? ๋น„์šฉ์ด ๋„ˆ๋ฌด ํฌ๋‹ค.
bool validateStudent(Student s);
Student plato;
bool platoIsOK = validateStudent(plato);
๏‚š plato๋กœ๋ถ€ํ„ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ s ์ดˆ๊ธฐํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด
Sudent ๋ณต์‚ฌ ์ƒ์„ฑ์ž ํ˜ธ์ถœ
๏‚š s๋Š” validateStudent๊ฐ€ ๋ณต๊ท€ํ•  ๋•Œ ์†Œ๋ฉธ
๏‚š ๊ฒฐ๊ตญ, ๋ณต์‚ฌ ์ƒ์„ฑ์ž 1๋ฒˆ, ์†Œ๋ฉธ์ž 1๋ฒˆ
๏‚š Student๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค string ๊ฐ์ฒด 2๊ฐœ
์ƒ์„ฑ
๏‚š Student๊ฐ์ฒด๋Š” Person๊ฐ์ฒด ํŒŒ์ƒ์ด๋ฏ€๋กœ
Person ์ƒ์„ฑ, string ๊ฐ์ฒด 2๊ฐœ ์ƒ์„ฑ
๏‚š ์†Œ๋ฉธ๋„ ์ƒ์„ฑ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€โ€ฆ
reference-to-const
๏‚š ํ˜ธ์ถœ์— ๋”ฐ๋ฅด๋Š” ๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
bool validateStudent(const Student& s); // ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฐ์ฒด ๊ฐ™์€ ๊ฒƒ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—
// ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž๊ฐ€ ์ „ํ˜€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.
// const๋กœ ์ „๋‹ฌ๋œ student ๊ฐ์ฒด๋ฅผ ๋ณดํ˜ธ
๋ณต์‚ฌ์†์‹ค ๋ฌธ์ œ(slicing problem)
class Window {
public:
โ€ฆ
std::string name() const;
virtual void display() const;
};
class WindowWithScrollBars : public Window {
public:
โ€ฆ
virtual void display() const;
};
void printNameAndDisplay(Window s)
{
std::cout << w.name();
w.display();
}
WindowWithScrollBars wwsb;
printNameAndDisplay(wwsb);
๋ณต์‚ฌ์†์‹ค ๋ฌธ์ œ
๏‚š ๋งค๊ฐœ๋ณ€์ˆ˜ w ์ƒ์„ฑ๋œ๋‹ค.
๏‚š ํ•˜์ง€๋งŒ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ Windows ๊ฐ์ฒด์ด๋ฏ€๋กœ, ์ด ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์€ WindowWithScrollBars ๊ฐ์ฒด์˜ ๊ณ ์œ 
์ •๋ณด๋“ค์€ ์†์‹ค๋œ๋‹ค.
๏‚š ๊ฒฐ๊ตญ, ํ˜ธ์ถœํ•˜๋Š” display()ํ•จ์ˆ˜๋„ Windows ๊ฐ์ฒด์˜ ๊ฒƒ์ด๋‹ค.
๋ณต์‚ฌ์†์‹ค ๋ฌธ์ œ ํ•ด๊ฒฐ
void printNameAndDisplay(const Windows& w)
{
std::coutn << w.name();
w.display();
}
w๋ฅผ ์ฐธ์กฐ์ž๋กœ ์ „๋‹ฌํ•˜๋ฉด w๋Š” ์–ด๋–ค ์ข…๋ฅ˜์˜ ์œˆ๋„์šฐ๊ฐ€ ๋„˜๊ฒจ์ง€๋”๋ผ๊ณ  ๊ทธ ์œˆ๋„์šฐ์˜ ์„ฑ์งˆ์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค.
ํ•จ์ˆ˜์—์„œ ๊ฐ์ฒด ๋ฐ˜ํ™˜ํ• ๋•Œ ์ฐธ์กฐ์ž ๋ฐ˜ํ™˜ํ•˜์ง€๋ง์ž
class Rational {
public :
Rational(int numerator = 0, int denominator = 1);
โ€ฆ
private :
int n, d;
friend
const Rational
operator*(const Rational& lhs, const Rational rhs);
};
Rational a(1, 2);
Rational b(3, 5);
Rational c = a * b; // ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ ์ฐธ์กฐ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค.
์Šคํƒ์„ ์ด์šฉํ•œ ๊ฐ์ฒด ๋ฐ˜ํ™˜
cosnt Rational& operation*(const Rational& lhs, const Rational& rhs)
{
Rational result(lhs.n * rhs.n, lhs.d * rhs.d); // ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ
retrun result; // result๋Š” ์ง€์—ญ๊ฐ์ฒด์œผ๋กœ ํ•จ์ˆ˜๊ฐ€ ๋๋‚  ๋•Œ ์†Œ๋ฉธ๋จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ฐธ์กฐ์ž๋ฅผ ๋ฐ˜ํ™˜
}
ํž™์„ ์ด์šฉํ•œ ๊ฐ์ฒด ๋ฐ˜ํ™˜
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational *result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d); // ์ƒ์„ฑ์ž ํ˜ธ์ถœ, delete ๋ถ€๋‹ด
return *result;
}
static์„ ์ด์šฉํ•œ ๊ฐ์ฒด ๋ฐ˜ํ™˜
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
static Rational result; // ๋ฐ˜ํ™˜ํ•  ์ฐธ์กฐ์ž๊ฐ€ ๊ฐ€๋ฆฌํ‚ฌ ์ •์ ๊ฐ์ฒด
result = โ€ฆ;
return result;
}
์ •์ ๊ฐ์ฒด๋Š” ๊ณต์œ ํ•˜๋Š” ๊ฐ’์ด๋ฏ€๋กœ ํ™œ์šฉ์— ์ œํ•œ์ด ์žˆ์„ ๋ฟ๋”๋Ÿฌ, ์Šค๋ ˆ๋”” ์•ˆ์ „์„ฑ ๋ฌธ์ œ๋„ ์žˆ๋‹ค.
๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•
inline const Rational operator*(const Rational& 1hs, const Rational& rhs)
{
return Rational(lhs.n * rhs.n, lhs,d * rsh.d);
}
์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ •๋„์ด๋‹ค.
๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๊ฐ€ ์„ ์–ธ๋  ๊ณณ์€ private
๏‚š private์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์จ์•ผ ํ•œ๋‹ค.
๏‚š ์–ด๋–ค ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋Š” public์ด๊ณ , ์–ด๋–ค ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋Š” private์ด๋ผ๋ฉด ์ผ๊ด€์„ฑ์ด ์‚ฌ๋ผ์ง„๋‹ค.
๏‚š ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•ด ๋‘๋ฉด, ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ๋‚˜์ค‘์— ๊ณ„์‚ฐ์‹์œผ๋กœ
๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.(์บก์Аํ™”, encapsulation)
๏‚š public ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๊ฐ€ ์žˆ๊ณ , ์ด๊ฒƒ์„ ์ œ๊ฑฐํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์บก์Аํ™”๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
๏‚š protected๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค.
๏‚š ๊ฒฐ๊ตญ์€ ์บก์Аํ™”๋ฅผ ๊ณ ๋ คํ•˜์˜€์„ ๋•Œ, ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋Š” private์— ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ๋‹ต์ด๋‹ค.
๋ฉค๋ฒ„ํ•จ์ˆ˜๋ณด๋‹ค๋Š” ๋น„๋ฉค๋ฒ„ ๋น„ํ”„๋ Œ๋“œ ํ•จ์ˆ˜
class WebBrowser {
public:
โ€ฆ
void clearCache();
void clearHistory();
void removeCookies();
}
class WebBrowser {
public:
โ€ฆ
void clearEverything(); // clearCache,
// clearHistory,
// removeCookies
โ€ฆ
};
๋น„๋ฉค๋ฒ„ ๋ฒ„์ „
void clearBrowser (WebBrowser& wb)
{
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}
๋ฉค๋ฒ„ ๋ฒ„์ „์ด ์ข‹์„๊นŒ? ๋น„๋ฉค๋ฒ„ ๋ฒ„์ „์ด ์ข‹์„๊นŒ?
๋น„๋ฉค๋ฒ„ ๋ฒ„์ „์˜ ์žฅ์ 
๏‚š ์บก์Аํ™”
๏‚š ํ”ผํ‚ค์ง• ์œ ์—ฐ์„ฑ(packaging flexibility)๊ฐ€ ๋†’์•„์ง„๋‹ค.
๏‚š ์ปดํŒŒ์ผ ์˜์กด๋„๋„ ๋‚ฎ์ถ˜๋‹ค.
๏‚š ํ™•์žฅ์„ฑ์ด ๋†’์•„์ง„๋‹ค.
๏‚š ๊ฒฐ๊ตญ, ๋น„๋ฉค๋ฒ„ ๋ฐฉ๋ฒ•์ด ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ณด๋‹ค ์—ฌ๋Ÿฌ๋ชจ๋กœ ๋‚ซ๋‹ค.
namespace๋ฅผ ํ™œ์šฉํ•œ ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜
namespace WebBrowserStuff {
class WebBrowser {โ€ฆ};
void clearBrowser {WebBrowser& wb};
โ€ฆ
}
namesapce๋ฅผ ํ™œ์šฉํ•œ ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜์˜ ์žฅ์ 
๏‚š namespace๋Š” class์™€ ๋‹ฌ๋ฆฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์†Œ์Šค ํŒŒ์ผ์— ๋‚˜๋‰˜์–ด ํฉ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
๏‚š ๋‹ค์‹œ ๋งํ•ด, ํ•„์š”ํ•  ๋•Œ ๊ธฐ๋Šฅ์„ ๋ถˆ๋Ÿฌ๋‹ค ์“ฐ๋ฉด ๋œ๋‹ค. WebBrowser๊ฐ์ฒด๊ฐ€ ์—†์–ด๋„ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
๏‚š ์‘์šฉ๋„๊ฐ€ ๋†’์€ ํŽธ์˜ ํ•จ์ˆ˜๋“ค๊ณผ ์‘์šฉ๋„๊ฐ€ ๋‚ฎ์€ ํŽธ์˜ ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜์กด์„ฑ์—์„œ ๋น„
๊ต์  ์ž์œ ๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค.
๏‚š ํด๋ž˜์Šค ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๊ธฐ๋Šฅ์„ ์ชผ๊ฐœ๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
๏‚š ํŽธ์˜ ํ•จ์ˆ˜ ์ „์ฒด๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ—ค๋” ํŒŒ์ผ์—(๊ทธ๋Ÿฌ๋‚˜ ํ•˜๋‚˜์˜ namespace) ๋‚˜๋ˆ„์–ด ๋†“์œผ๋ฉด ํŽธ์˜ ํ•จ์ˆ˜ ์ง‘
ํ•ฉ์˜ ํ™•์žฅ๋„ ์‰ฌ์›Œ์ง„๋‹ค. ํ•ด๋‹น ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋น„๋ฉค๋ฒ„ ๋น„ํ”„๋ Œ๋“œ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋.
ํƒ€์ž…๋ณ€ํ™˜์ด ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ ์šฉ๋œ๋‹ค๋ฉด ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ
// ์œ ๋ฆฌ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค
class Rational {
public:
Rational(int numerator = 0, int denominator = 1);
int numerator() const;
int denominator() const;
const Rational operator*(const Rational& rhs) const;
private:
โ€ฆ
};
Rational oneEighth(1, 8);
Rational oneHalf(1, 2);
Rational result = oneHalf * oneEighth; // OK
result = result * oneEighth; // OK
result = oneHalf * 2; // OK
result = 2 * oneHalf; // error
result = oneHalf.operator*(2); // OK
result = 2.operator*(oneHalf); // error
์•”์‹œ์  ํƒ€์ž… ๋ณ€ํ™˜์— ๋Œ€ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋จนํ˜€๋“ค๋ ค๋ฉด
๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฆฌ์ŠคํŠธ์— ๋“ค์–ด์žˆ์–ด์•ผ ํ•œ๋‹ค.
์•”์‹œ์  ๋ณ€ํ™˜์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด์„œ
class Rational {
โ€ฆ
};
const Rational operator*(const Rational& lhs, const Rational& rhs) // ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.
{ // ๋ชจ๋“  ์ธ์ž์— ๋Œ€ํ•ด ์•”์‹œ์  ํƒ€์ž… ๋ณ€ํ™˜
return Raional(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator());
}
Rational oneFourth(1, 4);
Rational result;
result = oneFourth * 2;
result = 2 * oneFourth;
์˜ˆ์™ธ๋ฅผ ๋˜์ง€์ง€ ์•Š๋Š” swap
// ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” swap
namespce std {
template<typename T>
void swap(T& a, T& b)
{
T temp(a);
a = b;
b = temp;
}
}
pimpl ๊ด€์šฉ๊ตฌ
class Widget Impl {
public :
โ€ฆ
private :
int a, b, c;
std::vector<double> V;
โ€ฆ
};
class Widget {
public :
Widget (const Widget& rhs);
Widget& operator = (const Widget& rhs)
{
โ€ฆ
*pImpl = *(rhs.pImpl);
โ€ฆ
}
โ€ฆ
private :
WidgetImpl *pImpl;
};
ํ‘œ์ค€ swap ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋นˆํ‹ˆ
๏‚š ์œ„์˜ Widget ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋งž๋ฐ”๊พผ๋‹ค๋ฉด? pImplํฌ์ธํ„ฐ๋งŒ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
๏‚š Widget ๊ฐ์ฒด ์„ธ ๊ฐœ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ , WidgetImpl ๊ฐ์ฒด ์„ธ ๊ฐœ๋„ ๋ณต์‚ฌํ•œ๋‹ค.
๏‚š ๋น„ํšจ์œจ์ ์ด๋‹ค.
std::swap ํŠน์ˆ˜ํ™”
namespace std {
template<> // ์™„์ „ ํ…œํ”Œ๋ฆฟ ํŠน์ˆ˜ํ™”๋ฅผ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์•Œ๋ ค ์ค€๋‹ค.
void swap<Widget>(Widget& a, Widget& b)
{
swap(a.pImpl, b.pImpl);
}
}
class Widget {
public :
โ€ฆ
void swap(Widget& other)
{
using std::swap;
swap(pImpl, other.pImpl);
}
โ€ฆ
};
namespace std {
template<>
void swap<Widget>(Widget& a, Widget& b)
{
a.swap(b);
}
}
ํ•จ์ˆ˜๋Š” ๋ถ€๋ถ„ ํŠน์ˆ˜ํ™”๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.
// Widget์ด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ
template<typename T>
class WidgetImpl {โ€ฆ};
template<typename T>
class Widget {โ€ฆ};
namespace std {
template<typename T>
void swap<Widget<T>>(Widget<T>& a,
Widget<T>& b)
{ a.swap(b); }
}
์œ„ ์ฝ”๋“œ๋Š” ์ ๋ฒ•ํ•˜์ง€ ์•Š๋‹ค.
C++์€ ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์˜ ๋ถ€๋ถ„ ํŠน์ˆ˜ํ™”๋Š” ์ธ์ •
ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์— ๋Œ€ํ•ด์„œ๋Š” ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์˜ ๋ถ€๋ถ„์  ํŠน์ˆ˜ํ™”๋Š” ์˜ค๋ฒ„๋กœ๋“œ
namespace std {
template<typename T>
void swap(Widget<T>& a,
Widget<T>& b)
{ a.swap(b) };
}
์œ„์˜ ์ฝ”๋“œ๋Š” ์œ ํšจํ•˜์ง€ ์•Š๋‹ค.
๏‚š std ๋‚ด์˜ ํ…œํ”Œ๋ฆฟ์— ๋Œ€ํ•œ ์™„์ „ ํŠน์ˆ˜ํ™”๋Š” OK
๏‚š std์— ์ƒˆ๋กœ์šด ํ…œํ”Œ๋ฆฟ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ OK ์•„
๋‹˜
ํ…œํ”Œ๋ฆฟ ์ „์šฉ ๋ฒ„์ „์œผ๋กœ ๋งŒ๋“ค์ž
namespace WidgetStuff {
โ€ฆ
template<typename T>
class Widget {โ€ฆ};
โ€ฆ
template<typename T> // ๋น„๋ฉค๋ฒ„ swap ํ•จ์ˆ˜
void swap(Widget<T> a, Widget<T> b) // ์ด๋ฒˆ์—” std ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹˜
{
a.swap(b);
}
}
์ธ์ž ๊ธฐ๋ฐ˜ ํƒ์ƒ‰(argument-dependent lookup) ํ˜น์€ ์พจ๋‹ˆ๊ทธ ํƒ์ƒ‰(Koenig lookup)
์–ด๋–ค swap์ด ํ˜ธ์ถœ๋ ๊นŒ?
template<typename T>
void doSomething(T& obj1, T& obj2)
{
โ€ฆ
swap(obj1, obj2);
โ€ฆ
}
๏‚š std์— ์žˆ๋Š” ์ผ๋ฐ˜ํ˜• swap?
๏‚š std์˜ ์ผ๋ฐ˜ํ˜•์„ ํŠน์ˆ˜ํ™”ํ•œ ๋ฒ„์ „?
๏‚š Tํƒ€์ž… ์ „์šฉ์˜ ๋ฒ„์ „
T ํƒ€์ž… ์ „์šฉ๋ฒ„์ „์ด ์šฐ์„  ํ˜ธ์ถœ, ์—†์œผ๋ฉด ์ผ๋ฐ˜ํ˜•
template<typename T>
void doSomething(T& obj1, T& obj2)
{
using std::swap; // std::swap์„ ์ด ํ•จ์ˆ˜ ์•ˆ์œผ๋กœ ๋Œ์–ด์˜จ๋‹ค.
โ€ฆ
swap(obj1, obj2); // T ํƒ€์ž… ์ „์šฉ์˜ swap์„ ํ˜ธ์ถœํ•œ๋‹ค.
}
์ •๋ฆฌํ•˜๋ฉด
๏‚š std::swap์ด ํŠน์ • ํƒ€์ž…์— ๋Œ€ํ•ด ๋А๋ฆฌ๊ฒŒ ๋™์ž‘ํ•  ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๋ฉด swap ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ž.
๏‚š ๋ฉค๋ฒ„ swap์„ ์ œ๊ณตํ–ˆ์œผ๋ฉด, ์ด๋ฉค๋ฒ„๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋น„๋ฉค๋„ swap๋„ ์ œ๊ณตํ•˜์ž.
๏‚š ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋Š”, std::swap๋„ ํŠน์ˆ˜ํ™” ํ•˜์ž.
๏‚š ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ swap์„ ํ˜ธ์ถœํ•  ๋•Œ๋Š”, std::swap์— ๋Œ€ํ•œ using ์„ ์–ธ์„ ๋„ฃ์–ด ์ค€ ํ›„ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ•œ
์ • ์—†์ด swap์„ ํ˜ธ์ถœํ•˜์ž.
๏‚š ์‚ฌ์šฉ์ž ์ •์˜ ํƒ€์ž…์— ๋Œ€ํ•œ std ํ…œํ”Œ๋ฆฟ์„ ์™„์ „ ํŠน์ˆ˜ํ™”ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ std์— ์–ด๋–ค ๊ฒƒ์ด๋ผ๋„ ์ƒˆ๋กœ
์ถ”๊ฐ€ํ•  ์ˆ˜๋Š” ์—†๋‹ค.

Effective c++(chapter3,4)

  • 1.
  • 2.
    resource ๏‚š ์‚ฌ์šฉ์„ ์ผ๋‹จ๋งˆ์น˜๊ณ  ๋‚œ ํ›„์—” ์‹œ์Šคํ…œ์— ๋Œ๋ ค์ฃผ์–ด์•ผ ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ ๏‚š ๊ฐ€์ ธ์™€์„œ ๋‹ค ์ป์œผ๋ฉด ํ•ด์ œํ•ด์•ผ, ์ฆ‰ ๋†“์•„ ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ๏‚š ๋™์  ํ• ๋‹น ๋ฉ”๋ชจ๋ฆฌ(๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ ์„œ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉด memory leak)
  • 3.
    ์ž์›์„ ํ•ญ์ƒ ํ•ด์ œ๋˜๋„๋กํ•˜๋Š” ๋ฐฉ๋ฒ• ๏‚š ์ž์›์„ ๊ฐ์ฒด์— ๋„ฃ๊ณ  ๏‚š ๊ทธ ์ž์› ํ•ด์ œ๋ฅผ ์†Œ๋ฉธ์ž๊ฐ€ ๋งก๋„๋ก ํ•˜๋ฉฐ, ๏‚š ๊ทธ ์†Œ๋ฉธ์ž๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ๋˜๋„๋ก ๋งŒ๋“ ๋‹ค.
  • 4.
    auto_ptr ๏‚š ํฌ์ธํ„ฐ์™€ ๋น„์Šทํ•˜๊ฒŒ๋™์ž‘ํ•˜๋Š” ๊ฐ์ฒด(smart pointer) ๏‚š ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋Œ€์ƒ์— ๋Œ€ํ•ด ์†Œ๋ฉธ์ž๊ฐ€ ์ž๋™์œผ ๋กœ delete๋ฅผ ๋ถˆ๋Ÿฌ์ฃผ๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ๋‹ค. ๏‚š ํ•œ ๊ฐ์ฒด๋ฅผ ๋™์‹œ์— ๋‘˜์ด ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์—†๋‹ค. ๋ณต์‚ฌ์ƒ ์„ฑํ•˜๊ฑฐ๋‚˜ ๋Œ€์ž…ํ•˜๋ฉด ํ•œ auto_ptr์€ null์ด ๋œ๋‹ค. std::auto_ptr<Investment>(createInvestment ());
  • 5.
    ์ž์› ๊ด€๋ฆฌ์— ๊ฐ์ฒด๋ฅผ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•1 ๏‚š ์ž์›์„ ํš๋“ํ•œ ํ›„์— ์ž์› ๊ด€๋ฆฌ ๊ฐ์ฒด์— ๋„˜๊ธด๋‹ค. ๏‚š ์ž์› ํš๋“ ์ฆ‰ ์ดˆ๊ธฐํ™”(Resource Acquisition is Initialization:RAII) ๏‚š ์ž์› ํš๋“๊ณผ ์ž์› ๊ด€๋ฆฌ ๊ฐ์ฒด์˜ ์ดˆ๊ธฐํ™”๊ฐ€ ํ•œ ๋ฌธ์žฅ์—์„œ ์ด๋ฃจ์–ด ์ง„๋‹ค.
  • 6.
    ์ž์› ๊ด€๋ฆฌ์— ๊ฐ์ฒด๋ฅผ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•2 ๏‚š ์ž์› ๊ด€๋ฆฌ ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ์†Œ๋ฉธ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž์›์ด ํ™•์‹คํžˆ ํ•ด์ œ๋˜๋„๋ก ํ•œ๋‹ค. ๏‚š ์†Œ๋ฉธ์ž๋Š” ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ ์ž๋™์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ์‹คํ–‰ ์ œ์–ด๊ฐ€ ์–ด๋–ค ๊ฒฝ์œ„๋กœ ๋ธ”๋ก์„ ๋– ๋‚˜๋Š”๊ฐ€ ์— ์ƒ๊ด€์—†์ด ์ž์› ํ•ด์ œ๊ฐ€ ์ œ๋Œ€๋กœ ์ด๋ฃจ์–ด์ง€๊ฒŒ ๋œ๋‹ค.
  • 7.
    auto_ptr์˜ ํŠน์„ฑ std::auto_ptr<Investment>pInv1(creteInvestment()); std::auto_ptr<Investment>pInv2(pInv1); //pInv2๊ฐ€ ๊ฐ€๋ฆฌ์ง€๋Š” ๊ฐ์ฒด๋Š” pInv1์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด // pInv1์€ null, auto_ptr์˜ ํŠน์„ฑ pInv1 = pInv2 // pInv1๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ , pInv2๋Š” null
  • 8.
    auto_ptr๊ฐ€ ๋‹ต์ธ๊ฐ€? ๏‚š ๋ณต์‚ฌ๋™์ž‘์ด ์ด๋ฃจ์–ด์ง€๋ฉด ์ด์ „์˜ ๊ฒƒ์€ null์ด ๋œ๋‹ค. ๏‚š auto_ptr๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๋Š” ๋‘๊ฐœ ์ด์ƒ์˜ auto_ptr๊ฐ€ ๋ฌผ๊ณ  ์žˆ์œผ๋ฉด ์•ˆ ๋œ๋‹ค. ๏‚š ์ด ๋‘ ๊ฐ€์ง€ ํŠน์„ฑ๋•Œ๋ฌธ์— ๋™์ ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ๋ชจ๋“  ์ž์›์— ๋Œ€ํ•œ ๊ด€๋ฆฌ ๊ฐ์ฒด๋กœ์„œ auto_ptr๋ฅผ ์“ฐ๋Š” ๊ฒƒ์€ ์ตœ์„ ์ด ์•„๋‹Œ ๋“ฏํ•˜๋‹ค.
  • 9.
    ์ฐธ์กฐ ์นด์šดํŒ… ๋ฐฉ์‹์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๏‚š reference-counting smart pointer(RCSP) ๏‚š ํŠน์ •ํ•œ ์–ด๋–ค ์ž์›์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์™ธ๋ถ€ ๊ฐ์ฒด์˜ ๊ฐœ ์ˆ˜๋ฅผ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ๊ทธ ๊ฐœ์ˆ˜๊ฐ€ 0์ด ๋˜๋ฉด ํ•ด ๋‹น ์ž์›์œผ๋กœ ์‚ญ์ œํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๏‚š garbage collection ๋ฐฉ์‹๊ณผ ์œ ์‚ฌ ๏‚š std::tr1::shared_ptr<Investment>pInv(crea teInvestment());
  • 10.
    reference-counting smart pointer์˜ํŠน์„ฑ std::tr1::shared_ptr<Investment>pInv1(createInvestment()); std::tr1::shared_ptr<Investment>pInv1(pInv2); // auto_ptr๊ณผ ๋‹ฌ๋ฆฌ pInv1, pInv2๊ฐ€ // ๋™์‹œ์— ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. pInv1 = pInv2; // ๋ณ€ํ™”์—†์Œ
  • 11.
    auto_ptr, tr1::shared_ptr์˜ ๊ณตํ†ตํŠน์„ฑ ๏‚š ์†Œ๋ฉธ์ž ๋‚ด๋ถ€์—์„œ delete ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๏‚š delete [] ์—ฐ์‚ฐ์ž๊ฐ€ ์•„๋‹ˆ๋‹ค. ๏‚š ์ฆ‰, ๋™์  ํ• ๋‹นํ•œ ๋ฐฐ์—ด์— auto_ptr, tr1::shared_ptr์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋œ๋‹ค. std::auto_ptr<std::string>aps(new std::string[10]); // error std::tr1::shared_ptr<int> spi(new int[1024]);; // error
  • 12.
    RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋ ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜? ๏‚š ๋ณต์‚ฌ๋ฅผ ๊ธˆ์ง€ํ•œ๋‹ค. class Lock : private Uncopyable { public : โ€ฆ };
  • 13.
    RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋ ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜? ๏‚š ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์ž์›์— ๋Œ€ํ•ด ์ฐธ์กฐ ์นด์šดํŒ…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๏‚š ์ž์›์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋งˆ์ง€๋ง‰ ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋  ๋•Œ๊นŒ์ง€ ๊ทธ ์ž์›์„ ํ•ด์ œํ•˜๋ฉด ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ ๏‚š tr1::shared_ptr๋ฅผ ์ด์šฉ? ๏‚š tr1::shared_ptr๋ฅผ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋  ๋•Œ ์ž์‹ ์ด ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋˜ ๋Œ€์ƒ์„ ์‚ญ์ œํ•˜๋„๋ก ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ ์— ์•ˆ ๋œ๋‹ค. ๏‚š tr1:shared_ptr๋Š” โ€ž์‚ญ์ œ์ž(delete)โ€Ÿ ์ง€์ •์„ ํ—ˆ์šฉํ•œ๋‹ค.
  • 14.
    shared_ptr ์‚ญ์ œ์ž ํ™œ์šฉ classLock { public : explicit Lock(Mutex *pm) // shared_ptr๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š”๋ฐ, ๊ฐ€๋ฆฌํ‚ฌ ํฌ์ธํ„ฐ๋กœ : mutexPtr(pm, unlock // Mutex ๊ฐ์ฒด์˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‚ญ์ œ์ž๋กœ unlock ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ { lock(mutexPtr.get()); ) private : std::tr1::shared_ptr<Mutex>mutexPtr; }
  • 15.
    RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋ ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜? ๏‚š ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์ž์›์„ ์ง„์งœ๋กœ ๋ณต์‚ฌํ•œ๋‹ค. ๏‚š ๊นŠ์€ ๋ณต์‚ฌ(deep copy)
  • 16.
    RAII ๊ฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋ ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋‚˜? ๏‚š ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์ž์›์˜ ์†Œ์œ ๊ถŒ์„ ์˜ฎ๊ธด๋‹ค.
  • 17.
    ๋ช…์‹œ์  ๋ณ€ํ™˜(explicit conversion) ๏‚štr1::shared_ptr ๋ฐ auto_ptr์€ ๋ช…์‹œ์  ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” get์ด๋ผ๋Š” ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๏‚š get ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“  ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๊ฐ์ฒด์— ๋“ค์–ด์žˆ๋Š” ์‹ค์ œ ํฌ์ธํ„ฐ๋ฅผ ์–ป์–ด๋‚ธ๋‹ค. std::tr1::shared_ptr<Investment> pInv(createInvestment()); int daysHeld(const Investment *pi); // int days = daysHeld(pInv); // error int days = daysHeld(pInv.get());
  • 18.
    ์ž์› ์ ‘๊ทผ๊ณผ ๋ช…์‹œ์ ,์•”์‹œ์  ๋ณ€ํ™˜ ๏‚š ์•ˆ์ „์„ฑ๋งŒ ๋”ฐ์ง€๋งŒ ๋ช…์‹œ์  ๋ณ€ํ™˜์ด ๋Œ€์ฒด์ ์œผ๋กœ ๋‚ซ๋‹ค. ๏‚š ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž ํŽธ์˜์„ฑ์„ ๋†“๊ณ  ๋ณด๋ฉด ์•”์‹œ์  ๋ณ€ํ™˜์ด ๊ดœ์ฐฎ๋‹ค. ๏‚š โ€œ๋งž๊ฒŒ ์“ฐ๊ธฐ์—๋Š” ์‰ฝ๊ฒŒ, ํ‹€๋ฆฌ๊ฒŒ ์“ฐ๊ธฐ์—๋Š” ์–ด๋ ต๊ฒŒโ€œ
  • 19.
    new ๏‚š ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ๋‹ค. ๏‚šํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•ด ํ•œ ๊ฐœ ์ด์ƒ์˜ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
  • 20.
    delete ๏‚š ๊ธฐ์กด์— ํ• ๋‹น๋œ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•ด ํ•œ ๊ฐœ ์ด์ƒ์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ๏‚š ๊ทธ ํ›„์— ๊ทธ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋œ๋‹ค.
  • 21.
    ๊ฐ์ฒด ๋ฐฐ์—ด delete st::string*stringPtr1 = new std::string; st::string *stringPtr1 = new std::string[100]; โ€ฆ delete stringPtr1; delete [] stringPtr2; typedef std::string AddressLines[4]; std::string *pal = new AddressLines // delete pal; delete [] pal;
  • 22.
    new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋Š”์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋กœโ€ฆ int priority(); void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); // processWidget(new Widget, priority()); error! processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority()); std::tr1::shared_ptr์˜ ์ƒ์„ฑ์ž๋Š” explicit๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— โ€žnew Widgetโ€Ÿํ‘œํ˜„์‹์— ์˜ํ•ด ๋งŒ๋“ค์–ด ์ง„ ํฌ์ธํ„ฐ๊ฐ€ tr1::shared_ptr ํƒ€์ž…์˜ ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๋Š” ์•”์‹œ์ ์ธ ๋ณ€ํ™˜์ด ์—†๋‹ค.
  • 23.
    ๋งค๊ฐœ๋ณ€์ˆ˜ ํ˜ธ์ถœ ์ˆœ์„œ์—๋”ฐ๋ฅธ ์œ„ํ—˜์„ฑ processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority()); ์—ฐ์‚ฐ์ด ์‹คํ–‰๋˜๋Š” ์ˆœ์„œ priority -> โ€œnew Widgetโ€ -> tr1::shared_ptr? ๋ฐ˜๋“œ์‹œ ์œ„์˜ ์ˆœ์„œ๋Œ€๋กœ ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. priority๊ฐ€ ๋ช‡ ๋ฒˆ์งธ๋กœ ํ˜ธ์ถœ๋ ์ง€๋Š” ๋ชจ๋ฅธ๋‹ค. ๋ฌธ์ œ๋Š” priority ํ˜ธ์ถœ๋ถ€๋ถ„์—์„œ error๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด โ€œnew Widgetโ€์œผ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ํฌ์ธํ„ฐ๊ฐ€ ์œ ์‹ค๋  ์ˆ˜ ์žˆ๋‹ค.
  • 24.
    ํ•ด๊ฒฐ์ฑ… std::tr1::shared_ptr<Widget> pw(new widget);// new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์— processWidget(pw, priority()); // prority ํ˜ธ์ถœ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ํฌ์ธํ„ฐ ์œ ์‹ค ์—†์Œ // memory leak ๋ฐฉ์ง€ ๊ทธ๋ž˜์„œ new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋กœ ๋„ฃ๋Š” ์ฝ”๋“œ๋Š” ๋ณ„๋„์˜ ํ•œ ๋ฌธ์žฅ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
  • 25.
  • 26.
    ์ œ๋Œ€๋กœ ์“ฐ๊ธฐ ์‰ฝ๊ฒŒ,์—‰ํ„ฐ๋ฆฌ๋กœ ์“ฐ๊ธฐ ์–ด๋ ต๊ฒŒ class Date { public : Date(int month, int day, int year); โ€ฆ }; Date d(30, 3, 1995); // ์›”, ์ผ์ด ๋ฐ”๋€œ Date d(3, 40, 1955); // ์ผ์ด ์ด์ƒํ•œ ๊ฐ’ struct Day { explicit Day(int d) : val (d) {} int val; };
  • 27.
    class Date { public: Date(constMonth& m, const Day& d, const Year& y); โ€ฆ }; Date d(30, 3, 1955) // ์ž๋ฃŒํ˜•์ด ํ‹€๋ ธ๋‹ค. Date d(Day(30), Month(3), Year(1995)); // ์ž๋ฃŒํ˜•์ด ํ‹€๋ ธ๋‹ค. Date d(Month(3), Day(30), Year(1995));
  • 28.
    Investment * createInvestment(); std::tr1::shared_ptr<Investment>createInvestment(); ๋ฐ˜ํ™˜๊ฐ’์ดshared_ptr์ด๋ผ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉ์ž๊ฐ€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. ์ด ๊ฐ์ฒด๋ฅผ ์‚ญ์ฒดํ•˜๋Š” ๊ฒƒ์„ ๊นœ๋นกํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋”๋ผ๋„ share_ptr๊ฐ€ ์•Œ์•„์„œ ํ•ด์ œํ•œ๋‹ค.
  • 29.
    tr1::shared_ptr์˜ ํŠน์„ฑ ์ด์šฉ1 ๏‚š์ƒ์„ฑ ์‹œ์ ์— ์ž์› ํ•ด์ œ ํ•จ์ˆ˜(โ€ž์‚ญ์ œ์žโ€ž)๋ฅผ ์—ฎ์„ ์ˆ˜ ์žˆ๋‹ค. std::tr1::shared_ptr<Investment>pInv(0, getRidOfInvestment); // error std::tr1::shared_ptr<Investment*>pInv(static_cast<Investment*>)(0), getRidOfInvestmentl // 0์€ int, tr1::share_ptr๊ฐ€ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ Investmet* ํƒ€์ž…์˜ ์‹ค์ œ ํฌ์ธํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— static_cast
  • 30.
    tr1::shared_ptr์˜ ํŠน์„ฑ ์ด์šฉ2 ๏‚š๊ต์ฐจ DLL ๋ฌธ์ œ ํ•ด๊ฒฐ ๏‚š ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ์— ์–ด๋–ค ๋™์  ๋งํฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ new๋ฅผ ์ผ๋Š”๋ฐ ๊ทธ ๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ•  ๋•Œ๋Š” ์ด์ „์˜ DLL๊ณผ ๋‹ค๋ฅธ DLL์— ์žˆ๋Š” delete๋ฅผ ์„ฐ์„ ๊ฒฝ์šฐ ๏‚š tr1::shared_ptr์˜ ๊ธฐ๋ณธ ์‚ญ์ œ์ž๋Š” tr1::shared_ptr์ด ์ƒ์„ฑ๋œ DLL๊ณผ ๋™์ผํ•œ DLL์—์„œ delete๋ฅผ ์‚ฌ์šฉํ•˜ ๋„๋ก ๋งŒ๋“ค์–ด์ ธ ์žˆ๋‹ค.
  • 31.
    ์ข‹์€ ํด๋ž˜์Šค ์„ค๊ณ„ ๏‚š์ƒˆ๋กœ ์ •์˜ํ•œ ํƒ€์ž…์˜ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์†Œ๋ฉธ์€ ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•˜๋Š”๊ฐ€? ๏‚š ๊ฐ์ฒด ์ดˆ๊ธฐํ™”๋Š” ๊ฐ์ฒด ๋Œ€์ž…๊ณผ ์–ด๋–ป๊ฒŒ ๋‹ฌ๋ผ์•ผ ํ•˜๋Š”๊ฐ€? ๏‚š ์ƒˆ๋กœ์šด ํƒ€์ž…์œผ๋กœ ๋งŒ๋“  ๊ฐ์ฒด๊ฐ€ ๊ฐ’์— ์˜ํ•ด ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ์— ์–ด๋–ค ์˜๋ฏธ๋ฅผ ์ค„ ๊ฒƒ์ธ๊ฐ€? ๏‚š ์ƒˆ๋กœ์šด ํƒ€์ž…์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ ๋ฒ•ํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ œ์•ฝ์€ ๋ฌด์—‡์œผ๋กœ ์žก์„ ๊ฒƒ์ธ๊ฐ€? ๏‚š ๊ธฐ์กด์˜ ํด๋ž˜์Šค ์ƒ์† ๊ณ„ํ†ต๋ง์— ๋งž์ถœ ๊ฒƒ์ธ๊ฐ€? ๏‚š ์–ด๋–ค ์ข…๋ฅ˜์˜ ํƒ€์ž… ๋ณ€ํ™˜์„ ํ—ˆ์šฉํ•  ๊ฒƒ์ธ๊ฐ€? (implicity, explicit) ๏‚š ์–ด๋–ค ์—ฐ์‚ฐ์ž์™€ ํ•จ์ˆ˜๋ฅผ ๋‘์–ด์•ผ ์˜๋ฏธ๊ฐ€ ์žˆ์„๊นŒ?
  • 32.
    ์ข‹์€ ํด๋ž˜์Šค ์„ค๊ณ„ ๏‚šํ‘œ์ค€ ํ•จ์ˆ˜๋“ค ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ํ—ˆ์šฉํ•˜์ง€ ๋ง ๊ฒƒ์ธ๊ฐ€? ๏‚š ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ๋ฉค๋ฒ„์— ๋Œ€ํ•œ ์ ‘๊ทผ๊ถŒํ•œ์€ ์–ด๋А ์ชฝ์— ์ค„ ๊ฒƒ์ธ๊ฐ€? ๏‚š โ€ž์„ ์–ธ๋˜์ง€ ์•Š์€ ์ธํ„ฐํŽ˜์ด์Šคโ€Ÿ๋กœ ๋ฌด์—‡์„ ๋‘˜ ๊ฒƒ์ธ๊ฐ€? ๏‚š ์ƒˆ๋กœ ๋งŒ๋“œ๋Š” ํƒ€์ž…์ด ์–ผ๋งˆ๋‚˜ ์ผ๋ฐ˜์ ์ธ๊ฐ€? ๏‚š ์ •๋ง๋กœ ํ•„์š”ํ•œ ํƒ€์ž…์ธ๊ฐ€?
  • 33.
    pass_by_value? class Person { public: Person(); virtual ~ Person(); โ€ฆ private : std::string name; std::string address; }; class Student : public Person { public : Student(); ~Student(); โ€ฆ private: std::string schoolName; std::string schoolAddress; };
  • 34.
    pass-by-value? ๋น„์šฉ์ด ๋„ˆ๋ฌดํฌ๋‹ค. bool validateStudent(Student s); Student plato; bool platoIsOK = validateStudent(plato); ๏‚š plato๋กœ๋ถ€ํ„ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ s ์ดˆ๊ธฐํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด Sudent ๋ณต์‚ฌ ์ƒ์„ฑ์ž ํ˜ธ์ถœ ๏‚š s๋Š” validateStudent๊ฐ€ ๋ณต๊ท€ํ•  ๋•Œ ์†Œ๋ฉธ ๏‚š ๊ฒฐ๊ตญ, ๋ณต์‚ฌ ์ƒ์„ฑ์ž 1๋ฒˆ, ์†Œ๋ฉธ์ž 1๋ฒˆ ๏‚š Student๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค string ๊ฐ์ฒด 2๊ฐœ ์ƒ์„ฑ ๏‚š Student๊ฐ์ฒด๋Š” Person๊ฐ์ฒด ํŒŒ์ƒ์ด๋ฏ€๋กœ Person ์ƒ์„ฑ, string ๊ฐ์ฒด 2๊ฐœ ์ƒ์„ฑ ๏‚š ์†Œ๋ฉธ๋„ ์ƒ์„ฑ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€โ€ฆ
  • 35.
    reference-to-const ๏‚š ํ˜ธ์ถœ์— ๋”ฐ๋ฅด๋Š”๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. bool validateStudent(const Student& s); // ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฐ์ฒด ๊ฐ™์€ ๊ฒƒ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— // ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž๊ฐ€ ์ „ํ˜€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค. // const๋กœ ์ „๋‹ฌ๋œ student ๊ฐ์ฒด๋ฅผ ๋ณดํ˜ธ
  • 36.
    ๋ณต์‚ฌ์†์‹ค ๋ฌธ์ œ(slicing problem) classWindow { public: โ€ฆ std::string name() const; virtual void display() const; }; class WindowWithScrollBars : public Window { public: โ€ฆ virtual void display() const; }; void printNameAndDisplay(Window s) { std::cout << w.name(); w.display(); } WindowWithScrollBars wwsb; printNameAndDisplay(wwsb);
  • 37.
    ๋ณต์‚ฌ์†์‹ค ๋ฌธ์ œ ๏‚š ๋งค๊ฐœ๋ณ€์ˆ˜w ์ƒ์„ฑ๋œ๋‹ค. ๏‚š ํ•˜์ง€๋งŒ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ Windows ๊ฐ์ฒด์ด๋ฏ€๋กœ, ์ด ๊ฐ์ฒด๋ฅผ ์ƒ์†๋ฐ›์€ WindowWithScrollBars ๊ฐ์ฒด์˜ ๊ณ ์œ  ์ •๋ณด๋“ค์€ ์†์‹ค๋œ๋‹ค. ๏‚š ๊ฒฐ๊ตญ, ํ˜ธ์ถœํ•˜๋Š” display()ํ•จ์ˆ˜๋„ Windows ๊ฐ์ฒด์˜ ๊ฒƒ์ด๋‹ค.
  • 38.
    ๋ณต์‚ฌ์†์‹ค ๋ฌธ์ œ ํ•ด๊ฒฐ voidprintNameAndDisplay(const Windows& w) { std::coutn << w.name(); w.display(); } w๋ฅผ ์ฐธ์กฐ์ž๋กœ ์ „๋‹ฌํ•˜๋ฉด w๋Š” ์–ด๋–ค ์ข…๋ฅ˜์˜ ์œˆ๋„์šฐ๊ฐ€ ๋„˜๊ฒจ์ง€๋”๋ผ๊ณ  ๊ทธ ์œˆ๋„์šฐ์˜ ์„ฑ์งˆ์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค.
  • 39.
    ํ•จ์ˆ˜์—์„œ ๊ฐ์ฒด ๋ฐ˜ํ™˜ํ• ๋•Œ์ฐธ์กฐ์ž ๋ฐ˜ํ™˜ํ•˜์ง€๋ง์ž class Rational { public : Rational(int numerator = 0, int denominator = 1); โ€ฆ private : int n, d; friend const Rational operator*(const Rational& lhs, const Rational rhs); };
  • 40.
    Rational a(1, 2); Rationalb(3, 5); Rational c = a * b; // ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ ์ฐธ์กฐ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค.
  • 41.
    ์Šคํƒ์„ ์ด์šฉํ•œ ๊ฐ์ฒด๋ฐ˜ํ™˜ cosnt Rational& operation*(const Rational& lhs, const Rational& rhs) { Rational result(lhs.n * rhs.n, lhs.d * rhs.d); // ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ retrun result; // result๋Š” ์ง€์—ญ๊ฐ์ฒด์œผ๋กœ ํ•จ์ˆ˜๊ฐ€ ๋๋‚  ๋•Œ ์†Œ๋ฉธ๋จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ฐธ์กฐ์ž๋ฅผ ๋ฐ˜ํ™˜ }
  • 42.
    ํž™์„ ์ด์šฉํ•œ ๊ฐ์ฒด๋ฐ˜ํ™˜ const Rational& operator*(const Rational& lhs, const Rational& rhs) { Rational *result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d); // ์ƒ์„ฑ์ž ํ˜ธ์ถœ, delete ๋ถ€๋‹ด return *result; }
  • 43.
    static์„ ์ด์šฉํ•œ ๊ฐ์ฒด๋ฐ˜ํ™˜ const Rational& operator*(const Rational& lhs, const Rational& rhs) { static Rational result; // ๋ฐ˜ํ™˜ํ•  ์ฐธ์กฐ์ž๊ฐ€ ๊ฐ€๋ฆฌํ‚ฌ ์ •์ ๊ฐ์ฒด result = โ€ฆ; return result; } ์ •์ ๊ฐ์ฒด๋Š” ๊ณต์œ ํ•˜๋Š” ๊ฐ’์ด๋ฏ€๋กœ ํ™œ์šฉ์— ์ œํ•œ์ด ์žˆ์„ ๋ฟ๋”๋Ÿฌ, ์Šค๋ ˆ๋”” ์•ˆ์ „์„ฑ ๋ฌธ์ œ๋„ ์žˆ๋‹ค.
  • 44.
    ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์˜ฌ๋ฐ”๋ฅธ๋ฐฉ๋ฒ• inline const Rational operator*(const Rational& 1hs, const Rational& rhs) { return Rational(lhs.n * rhs.n, lhs,d * rsh.d); } ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ •๋„์ด๋‹ค.
  • 45.
    ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๊ฐ€ ์„ ์–ธ๋ ๊ณณ์€ private ๏‚š private์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์จ์•ผ ํ•œ๋‹ค. ๏‚š ์–ด๋–ค ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋Š” public์ด๊ณ , ์–ด๋–ค ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋Š” private์ด๋ผ๋ฉด ์ผ๊ด€์„ฑ์ด ์‚ฌ๋ผ์ง„๋‹ค. ๏‚š ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•ด ๋‘๋ฉด, ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ๋‚˜์ค‘์— ๊ณ„์‚ฐ์‹์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.(์บก์Аํ™”, encapsulation) ๏‚š public ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๊ฐ€ ์žˆ๊ณ , ์ด๊ฒƒ์„ ์ œ๊ฑฐํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์บก์Аํ™”๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๏‚š protected๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค. ๏‚š ๊ฒฐ๊ตญ์€ ์บก์Аํ™”๋ฅผ ๊ณ ๋ คํ•˜์˜€์„ ๋•Œ, ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋Š” private์— ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ๋‹ต์ด๋‹ค.
  • 46.
    ๋ฉค๋ฒ„ํ•จ์ˆ˜๋ณด๋‹ค๋Š” ๋น„๋ฉค๋ฒ„ ๋น„ํ”„๋ Œ๋“œํ•จ์ˆ˜ class WebBrowser { public: โ€ฆ void clearCache(); void clearHistory(); void removeCookies(); } class WebBrowser { public: โ€ฆ void clearEverything(); // clearCache, // clearHistory, // removeCookies โ€ฆ };
  • 47.
    ๋น„๋ฉค๋ฒ„ ๋ฒ„์ „ void clearBrowser(WebBrowser& wb) { wb.clearCache(); wb.clearHistory(); wb.removeCookies(); } ๋ฉค๋ฒ„ ๋ฒ„์ „์ด ์ข‹์„๊นŒ? ๋น„๋ฉค๋ฒ„ ๋ฒ„์ „์ด ์ข‹์„๊นŒ?
  • 48.
    ๋น„๋ฉค๋ฒ„ ๋ฒ„์ „์˜ ์žฅ์  ๏‚š์บก์Аํ™” ๏‚š ํ”ผํ‚ค์ง• ์œ ์—ฐ์„ฑ(packaging flexibility)๊ฐ€ ๋†’์•„์ง„๋‹ค. ๏‚š ์ปดํŒŒ์ผ ์˜์กด๋„๋„ ๋‚ฎ์ถ˜๋‹ค. ๏‚š ํ™•์žฅ์„ฑ์ด ๋†’์•„์ง„๋‹ค. ๏‚š ๊ฒฐ๊ตญ, ๋น„๋ฉค๋ฒ„ ๋ฐฉ๋ฒ•์ด ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ณด๋‹ค ์—ฌ๋Ÿฌ๋ชจ๋กœ ๋‚ซ๋‹ค.
  • 49.
    namespace๋ฅผ ํ™œ์šฉํ•œ ๋น„๋ฉค๋ฒ„ํ•จ์ˆ˜ namespace WebBrowserStuff { class WebBrowser {โ€ฆ}; void clearBrowser {WebBrowser& wb}; โ€ฆ }
  • 50.
    namesapce๋ฅผ ํ™œ์šฉํ•œ ๋น„๋ฉค๋ฒ„ํ•จ์ˆ˜์˜ ์žฅ์  ๏‚š namespace๋Š” class์™€ ๋‹ฌ๋ฆฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์†Œ์Šค ํŒŒ์ผ์— ๋‚˜๋‰˜์–ด ํฉ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ๏‚š ๋‹ค์‹œ ๋งํ•ด, ํ•„์š”ํ•  ๋•Œ ๊ธฐ๋Šฅ์„ ๋ถˆ๋Ÿฌ๋‹ค ์“ฐ๋ฉด ๋œ๋‹ค. WebBrowser๊ฐ์ฒด๊ฐ€ ์—†์–ด๋„ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ๏‚š ์‘์šฉ๋„๊ฐ€ ๋†’์€ ํŽธ์˜ ํ•จ์ˆ˜๋“ค๊ณผ ์‘์šฉ๋„๊ฐ€ ๋‚ฎ์€ ํŽธ์˜ ํ•จ์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜์กด์„ฑ์—์„œ ๋น„ ๊ต์  ์ž์œ ๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค. ๏‚š ํด๋ž˜์Šค ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๊ธฐ๋Šฅ์„ ์ชผ๊ฐœ๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ๏‚š ํŽธ์˜ ํ•จ์ˆ˜ ์ „์ฒด๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ—ค๋” ํŒŒ์ผ์—(๊ทธ๋Ÿฌ๋‚˜ ํ•˜๋‚˜์˜ namespace) ๋‚˜๋ˆ„์–ด ๋†“์œผ๋ฉด ํŽธ์˜ ํ•จ์ˆ˜ ์ง‘ ํ•ฉ์˜ ํ™•์žฅ๋„ ์‰ฌ์›Œ์ง„๋‹ค. ํ•ด๋‹น ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋น„๋ฉค๋ฒ„ ๋น„ํ”„๋ Œ๋“œ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋.
  • 51.
    ํƒ€์ž…๋ณ€ํ™˜์ด ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์—์ ์šฉ๋œ๋‹ค๋ฉด ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ // ์œ ๋ฆฌ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค class Rational { public: Rational(int numerator = 0, int denominator = 1); int numerator() const; int denominator() const; const Rational operator*(const Rational& rhs) const; private: โ€ฆ };
  • 52.
    Rational oneEighth(1, 8); RationaloneHalf(1, 2); Rational result = oneHalf * oneEighth; // OK result = result * oneEighth; // OK result = oneHalf * 2; // OK result = 2 * oneHalf; // error result = oneHalf.operator*(2); // OK result = 2.operator*(oneHalf); // error ์•”์‹œ์  ํƒ€์ž… ๋ณ€ํ™˜์— ๋Œ€ํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋จนํ˜€๋“ค๋ ค๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฆฌ์ŠคํŠธ์— ๋“ค์–ด์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • 53.
    ์•”์‹œ์  ๋ณ€ํ™˜์„ ๊ฐ€๋Šฅํ•˜๊ฒŒํ•˜๊ธฐ์œ„ํ•ด์„œ class Rational { โ€ฆ }; const Rational operator*(const Rational& lhs, const Rational& rhs) // ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์—ˆ๋‹ค. { // ๋ชจ๋“  ์ธ์ž์— ๋Œ€ํ•ด ์•”์‹œ์  ํƒ€์ž… ๋ณ€ํ™˜ return Raional(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator()); } Rational oneFourth(1, 4); Rational result; result = oneFourth * 2; result = 2 * oneFourth;
  • 54.
    ์˜ˆ์™ธ๋ฅผ ๋˜์ง€์ง€ ์•Š๋Š”swap // ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” swap namespce std { template<typename T> void swap(T& a, T& b) { T temp(a); a = b; b = temp; } }
  • 55.
    pimpl ๊ด€์šฉ๊ตฌ class WidgetImpl { public : โ€ฆ private : int a, b, c; std::vector<double> V; โ€ฆ }; class Widget { public : Widget (const Widget& rhs); Widget& operator = (const Widget& rhs) { โ€ฆ *pImpl = *(rhs.pImpl); โ€ฆ } โ€ฆ private : WidgetImpl *pImpl; };
  • 56.
    ํ‘œ์ค€ swap ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜๋นˆํ‹ˆ ๏‚š ์œ„์˜ Widget ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋งž๋ฐ”๊พผ๋‹ค๋ฉด? pImplํฌ์ธํ„ฐ๋งŒ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ๏‚š Widget ๊ฐ์ฒด ์„ธ ๊ฐœ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ , WidgetImpl ๊ฐ์ฒด ์„ธ ๊ฐœ๋„ ๋ณต์‚ฌํ•œ๋‹ค. ๏‚š ๋น„ํšจ์œจ์ ์ด๋‹ค.
  • 57.
    std::swap ํŠน์ˆ˜ํ™” namespace std{ template<> // ์™„์ „ ํ…œํ”Œ๋ฆฟ ํŠน์ˆ˜ํ™”๋ฅผ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์•Œ๋ ค ์ค€๋‹ค. void swap<Widget>(Widget& a, Widget& b) { swap(a.pImpl, b.pImpl); } }
  • 58.
    class Widget { public: โ€ฆ void swap(Widget& other) { using std::swap; swap(pImpl, other.pImpl); } โ€ฆ }; namespace std { template<> void swap<Widget>(Widget& a, Widget& b) { a.swap(b); } }
  • 59.
    ํ•จ์ˆ˜๋Š” ๋ถ€๋ถ„ ํŠน์ˆ˜ํ™”๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค. // Widget์ด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ template<typename T> class WidgetImpl {โ€ฆ}; template<typename T> class Widget {โ€ฆ}; namespace std { template<typename T> void swap<Widget<T>>(Widget<T>& a, Widget<T>& b) { a.swap(b); } } ์œ„ ์ฝ”๋“œ๋Š” ์ ๋ฒ•ํ•˜์ง€ ์•Š๋‹ค. C++์€ ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์˜ ๋ถ€๋ถ„ ํŠน์ˆ˜ํ™”๋Š” ์ธ์ • ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์— ๋Œ€ํ•ด์„œ๋Š” ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • 60.
    ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ์˜ ๋ถ€๋ถ„์ ํŠน์ˆ˜ํ™”๋Š” ์˜ค๋ฒ„๋กœ๋“œ namespace std { template<typename T> void swap(Widget<T>& a, Widget<T>& b) { a.swap(b) }; } ์œ„์˜ ์ฝ”๋“œ๋Š” ์œ ํšจํ•˜์ง€ ์•Š๋‹ค. ๏‚š std ๋‚ด์˜ ํ…œํ”Œ๋ฆฟ์— ๋Œ€ํ•œ ์™„์ „ ํŠน์ˆ˜ํ™”๋Š” OK ๏‚š std์— ์ƒˆ๋กœ์šด ํ…œํ”Œ๋ฆฟ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ OK ์•„ ๋‹˜
  • 61.
    ํ…œํ”Œ๋ฆฟ ์ „์šฉ ๋ฒ„์ „์œผ๋กœ๋งŒ๋“ค์ž namespace WidgetStuff { โ€ฆ template<typename T> class Widget {โ€ฆ}; โ€ฆ template<typename T> // ๋น„๋ฉค๋ฒ„ swap ํ•จ์ˆ˜ void swap(Widget<T> a, Widget<T> b) // ์ด๋ฒˆ์—” std ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹˜ { a.swap(b); } } ์ธ์ž ๊ธฐ๋ฐ˜ ํƒ์ƒ‰(argument-dependent lookup) ํ˜น์€ ์พจ๋‹ˆ๊ทธ ํƒ์ƒ‰(Koenig lookup)
  • 62.
    ์–ด๋–ค swap์ด ํ˜ธ์ถœ๋ ๊นŒ? template<typenameT> void doSomething(T& obj1, T& obj2) { โ€ฆ swap(obj1, obj2); โ€ฆ } ๏‚š std์— ์žˆ๋Š” ์ผ๋ฐ˜ํ˜• swap? ๏‚š std์˜ ์ผ๋ฐ˜ํ˜•์„ ํŠน์ˆ˜ํ™”ํ•œ ๋ฒ„์ „? ๏‚š Tํƒ€์ž… ์ „์šฉ์˜ ๋ฒ„์ „
  • 63.
    T ํƒ€์ž… ์ „์šฉ๋ฒ„์ „์ด์šฐ์„  ํ˜ธ์ถœ, ์—†์œผ๋ฉด ์ผ๋ฐ˜ํ˜• template<typename T> void doSomething(T& obj1, T& obj2) { using std::swap; // std::swap์„ ์ด ํ•จ์ˆ˜ ์•ˆ์œผ๋กœ ๋Œ์–ด์˜จ๋‹ค. โ€ฆ swap(obj1, obj2); // T ํƒ€์ž… ์ „์šฉ์˜ swap์„ ํ˜ธ์ถœํ•œ๋‹ค. }
  • 64.
    ์ •๋ฆฌํ•˜๋ฉด ๏‚š std::swap์ด ํŠน์ •ํƒ€์ž…์— ๋Œ€ํ•ด ๋А๋ฆฌ๊ฒŒ ๋™์ž‘ํ•  ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๋ฉด swap ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ž. ๏‚š ๋ฉค๋ฒ„ swap์„ ์ œ๊ณตํ–ˆ์œผ๋ฉด, ์ด๋ฉค๋ฒ„๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋น„๋ฉค๋„ swap๋„ ์ œ๊ณตํ•˜์ž. ๏‚š ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋Š”, std::swap๋„ ํŠน์ˆ˜ํ™” ํ•˜์ž. ๏‚š ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ swap์„ ํ˜ธ์ถœํ•  ๋•Œ๋Š”, std::swap์— ๋Œ€ํ•œ using ์„ ์–ธ์„ ๋„ฃ์–ด ์ค€ ํ›„ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ•œ ์ • ์—†์ด swap์„ ํ˜ธ์ถœํ•˜์ž. ๏‚š ์‚ฌ์šฉ์ž ์ •์˜ ํƒ€์ž…์— ๋Œ€ํ•œ std ํ…œํ”Œ๋ฆฟ์„ ์™„์ „ ํŠน์ˆ˜ํ™”ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ std์— ์–ด๋–ค ๊ฒƒ์ด๋ผ๋„ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜๋Š” ์—†๋‹ค.