U E D R , A S I H C RSS

More EffectiveC++/Exception

1. Exception

1.1. Item 9: Use destuctors to prevent resource leaks.

  • Item 9: ž›ƒˆ๋Š”ฑธ ๋ง‰๋Š” ŒŒดดž๋ฅผ ‚ฌšฉ•ด๋ผ.

€—ฌ๋ธ ๋™๋ฌผ๋“ค ด๋ž˜Šค๋ฅผ ๋งŒ๋“ค–ด ๋ณดž.

ALA๋Š” (Adorable Little Animalด๋‹ค.)
~cpp 
    class ALA{
    publid:
        virtual void processAdiption() = 0;
        ...
    };
    class Puppy: public ALA{
    publid:
        virtual void processAdiption();
        ...
    };
    class Kitten: pubic ALA{
    publid:
        virtual void processAdiption();
        ...
    };

ผ๋‹—ฌ๋Ÿฌ๋ถ„€ ŒŒ—„œ ๋ถ€„ฐ puppy™€ kitten™€ ‚คŠผ˜  •๋ณด๋ฅผ ด๋ ‡ฒŒ   ๋งŒ๋“ ‹ค. ‚ฌ‹ค Item 25— –ธธ‰•  virtual constructorฐ€  œฒฉง€๋งŒ, ผ๋‹šฐ๋ฆฌ— ๋ชฉ — ๋งž๋Š” •ˆ˜๋กœ ๋Œ€ฒด•œ‹ค.
~cpp 
    ALA * readALA(istream& s);

‹Œณผ ฐ™€ ๋А๋‚Œ(?)œผ๋กœ œ •œ‹ค.
~cpp 
    void processAdoptions( istream& dataSource)
    {
        while (dataSource) {
            ALA *pa = readALA(dataSource);
            pa->processAdoption();
            delete pa;
        }
    }
pa— •ด๋‹•˜๋Š” processAdoption()€ ˜ค๋ฅ˜‹œ— exception„ ๋˜„‹ค. •˜ง€๋งŒ, exception‹œ— •ด๋‹ฝ”๋“œฐ€ ๋ฉˆ˜‹ค๋ฉด "delete pa;"ฐ€ ˆ˜–‰๋˜ง€ •Š•„„œ ฒฐตญ ž›ƒˆ๋Š” šจณผฐ€ žˆ ง€ ธ๋ ‡๋‹ค๋ฉด ๋‹Œณผ ฐ™ผ๋‹˜ˆ™ธ ˜๋ฆฌ๋ฅผ •œ‹ค. ๋ฌผ๋ก  •ด๋‹•ˆ˜—„œ propagate•ฃผ–ด •ˆ˜ žฒด—„œ๋„ ˜ˆ™ธ๋ฅผ ๋ฐœƒ ‹œ‚จ๋‹ค.

~cpp 
    void processAdoptions( istream& dataSource)
    {
        while (dataSource) {
            ALA *pa = readALA(dataSource);
            try{
                pa->processAdoption();
            }
            catch ( ... ) {
                delete pa;
                throw;
            }
            delete pa;
        }
    }
๋ฐฉ๋ฒ•€ ˜ฌ๋ฐ”๋ฅด๋‹ค. ˜ˆ™ธ‹œ— •ด๋‹ฒด๋ฅผ ง€›Œ ๋ฒ„๋ฆฌ๋Š”ฒƒ, ธ๋ฆฌ  ฑด šฐ๋ฆฌฐ€ ๋ฐฐšด try-catch-throw๋ฅผ ถฉ‹žˆ ‚ฌšฉ•œ ฒƒด๋‹ค. •˜ง€๋งŒ.. ๋ณตžก•˜ง€ •Š€ฐ€? •ด๋‹ฝ”๋“œ๋Š” ๋งธ๋Œ€๋กœ Žผณ„‹ค.(˜„œ˜ ‘œ˜„) ธ๋ฆฌ  ฝ”๋“œ˜ ฐ€๋…„ฑ๋„ ๋–จ–ดง€๋ฉฐ, ฐจ›„ ด€๋ฆฌ ฐจ›—„œ ถ”ฐ€ ฝ”๋“œ˜ ๋ฐœƒ‹œ—๋„ –ด๋А ˜—ญ— ๋ณด•• ฒƒ ฐ€— ด€•˜—ฌ ๋ฌธ œ‹œ ๋œ‹ค.

—ฌธฐ—„œ žฌ๋ฏธžˆ๋Š” ธฐ๋ฒ•„ •ธฐ •ด๋ณธ๋‹ค. ฐจฐจ †Œœ๋  smart pointer™€ ๋”๋ถˆ–ด Standard C++ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ— ฌ•จ๋˜–ด žˆ๋Š” auto_ptr template ด๋ž˜Šค๋ฅผ šฉ•œ •ฒฐฑ…ธ๋ฐ auto_prt€ ด๋ ‡ฒŒ ƒฒผ๋‹ค.

~cpp 
    template<class T>
    class auto_ptr{
    public:
        auto_ptr(T *p = 0) : ptr(p) {}
    private:
        T *ptr;
    };

ธ๋ฆฌ  •ด๋‹น auto_prt˜  šฉ•œ ๋ชจŠต€ ๋‹Œณผ ฐ™ด ๋ณดธ๋‹ค.
~cpp 
    void processAdoptions(istream& dataSource)
    {
        while (dataSource){
            auto_ptr<ALA> pa(readALA(dataSource));
            pa->processAdoption();
        }
    }

˜ˆ™ธ ๋ฐœƒ‹œ— •ˆ˜ฐ€ ข…๋ฃŒ๋˜๋ฉด auto_ptrƒ˜ ฒด๋Š” ๋ฌดกฐฑด • œ๋œ‹ค.

žž ๋‹Œ ฝ”๋“œ๋„ ž›…€ฒƒด๋‹ค.
~cpp 
    void displayIntoInfo(const Information& info)
    {
        WINDOW_HANDLE w(createWindow());
        display info in window corresponding to w;
        destroyWindow(w);
    }

ผ๋ฐ˜ œผ๋กœ C˜ œ๋…œผ๋กœ œ—ฌ„ ”„๋กœธ๋žจ๋“ค€ createWindow and destroyWindow™€ ฐ™ด€๋ฆฌ•œ‹ค. ธ๋ ‡ง€๋งŒ ฒƒ —ญ‹œ destroyWindow(w)— ๋„‹ „— ˜ˆ™ธ ๋ฐœƒ‹œ ž›„ธ๋Š” ฒฝšฐฐ€ ƒธด๋‹ค. ธ๋ ‡๋‹ค๋ฉด ๋‹Œณผ ฐ™ด ๋ฐ”พธ–ด„œ •ด๋ณธ๋‹ค.

~cpp 
    class WidnowHandle{
    public:
        WindowHandle(WINDOW_HANDLE handle) : w(handle) {}
        ~WindowHandle() {destroyWindow(w); }
        
        operator WINDOW_HANDLE() {return w;}
    private:
        WINDOW_HANDLE w;
    
        WindowHandle(const WindowHandle&);
        WindowHandle&   operator=(const WindowHandle);

auto_ptrณผ ฐ™€ ›๋ฆฌด๋‹ค.
~cpp 
    void displayIntoInfo(const Information& info)
    {
        WINDOW_HANDLE w(createWindow());
        display info in window corresponding to w;
    }

1.2. Item 10: Prevent resource leaks in constructors.

  • Item 10: ƒ„ž—„œ ž›„ธ๋Š”ฑธ ๋ง‰•„ผ.

ž ๋‹‹ ด ๋ฉ€‹ฐ๋ฏธ๋””–ด ฃผ†Œ๋ก„ ๋งŒ๋“ ‹  ƒƒ•˜ , ”„๋กœธ๋žจ„ œ๋ณดž  „™”๋ฒˆ˜ธ, ๋ชฉ†Œ๋ฆฌ, ‚ฌ„, ด๋ฆ„ ๋”ฐœ„ฐ€ ๋“ค–ดฐ€•• ฒƒด๋‹ค. ๋‹Œ ๋Œ€•˜ ตฌ˜„ ฝ”๋“œ๋“ค„ ๋ณด๋ฉด
~cpp 
    class Image{
    public:
        Image(const string& imageDataFileName);
    ...
    };

    class AudioClip{
    public:
        AudioClip(const string& audioDataFileName);
        ...
    }
    class PhoneNumber{ ... };

    class BookEntry{
    public:
        BookEntry(const string& name,
                  const string& address = "",
                  const string& imageFileName = "",
                  const string& audioClipFileName = "");
        ~BookEntry();

        void addPhoneNumber(const PhoneNumber& number);
    
    private:
        string the Name;
        string the Address;
        list<phoneNumber> thePhones;
        Image *theImage;
        AudioClip *theAudioClip;
    };

ฐฐ˜ BookEntry๋Š” ด๋ฆ„ณผ ๋”๋ถˆ–ด ๋‹ค๋ฅธ •„๋“œ๋ฅผ ฐ€ง€  žˆœผ๋ฉฐ ธฐ๋ณธ ƒ„ž๋Š” ๋‹Œณผ ฐ™๋‹ค.

~cpp 
    // ธฐ๋ณธ ƒ„ž
    BookEntry::BookEntry(const string& name,
                         const string& address,
                         const string& imageFileName,
                         const string& audioClipFileName)
    :theName(name), theAddress(address), theImage(0), theAudioClip(0)
    {
        if (imageFileName != ""){       // ด๋ฏธง€๋ฅผ ƒ„•œ‹ค.
            theImage = new Image(imageFileName);
        }

        if (audioClipFileName != "") {  // †Œ๋ฆฌ  •๋ณด๋ฅผ ƒ„•œ‹ค.
            theAudioCilp = new AudioClip( audioClipFileName);
        }
    }
    BookEntry::~BookEntry()
    {
        delete theImage;
        delete theAudioClip;
    }

ƒ„ž๋Š” theImage™€ theAudioClip๋ฅผ null๋กœ ดˆธฐ™” ‹œ‚จ๋‹ค. C++ƒ—„œ nullฐ’ด๋ž€ deleteƒ—„œ˜ •ˆ „„ ๋ณดžฅ•œ‹ค. •˜ง€๋งŒ... œ„˜ ฝ”๋“œ‘— ๋‹Œ ฝ”๋“œ—„œ new๋กœ ƒ„• ‹œ— ˜ˆ™ธฐ€ ๋ฐœƒ๋œ‹ค๋ฉด?
~cpp 
    if (audioClipFileName != "") {
        theAudioClip = new AudioClip(audioClipFileName);
    }

žž ˜ˆ๋ฅผ๋“ค–ด„œ ด๋Ÿฐ •ˆ˜—„œ ˜ˆ™ธ ˜๋ฆฌ๋ฅผ ••• ฒƒด๋‹ค.
~cpp 
    void testBookEntryClass()
    {
        BookEntry b( "Addison-Wesley Publishing Company", "One Jacob Way, Reading, MA 018678");
        ...
    }

ด๋ ‡ฒŒ try-catch-throw๋กœ ๋งด๋‹ค.
~cpp 
    void testBookEntryClass()
    {
        BookEntry *pb = 0;
        try{
            pb = new BookEntry( "Addison-Wesley Publishing Company", "One Jacob Way, Reading, MA 018678");
        }
        catch ( ... ) {
            delete pb;
            throw;
        }
        delete pb;
    }

ด๋ ‡ฒŒ •ด๋„ —ฌ „žˆ ๋ฌธ œ๋Š” ๋‚จ๋Š”๋‹ค. ๋ฌด—‡ด๋ƒ •˜๋ฉด, ๋งŒ•BookEntry˜ ƒ„ž‘—„œ AudioClip ฒด ƒ„‘— ˜ˆ™ธ๋ฅผ propagate•˜๋ฉด ๋ฐ”๋กœ œ„ ฝ”๋“œ‘ pb ฌ„— null„ ๋ฐ˜™˜•ด ๋ฒ„๋ฆฐ๋‹ค. ๋ฐ˜๋‚ฉ๋œ ด๋ ‡ฒŒ ๋˜๋ฉด ด๋ฏธ  •ƒ œผ๋กœ ƒ„ฑ๋œ theImage๋ฅผ ง€šฐง€ ๋ชป•˜๋Š” ‚ฌƒœฐ€ ๋ฐœƒ•ด ๋ฒ„๋ฆฌ๋Š” ฒƒด๋‹ค.

ธ๋ ‡๋‹ค๋ฉด ƒ„ž˜ ๋‚ด๋ถ€—„œ‹‹œ try-catch-throw๋กœ ••• ฒƒด๋‹ค.

~cpp 
    BookEntry::BookEntry(const string& name,
                         const string& address,
                         const string& imageFileName,
                         const string& audioClipFileName)
    :theName(name), theAddress(address), theImage(0), theAudioClip(0)
    {
        try{
            if (imageFileName != ""){
                theImage = new Image(imageFileName);
            }

            if (audioClipFileName != "") {
                theAudioCilp = new AudioClip( audioClipFileName);
            }
        }
        catch (...){
            delete theImage;
            delete theAudioClip;
            throw;
        }
    }

ž ด๋ ‡ฒŒ •ฃผ๋ฉด ๋ฌธ œ ๋ ฒƒ—†๋‹ค. ž ƒƒœ— refactoring•„š”•œ ฝ”๋“œ๋“คด ๋ณดฒƒด๋‹•˜ ‹ค. delete๋ถ€๋ถ„„ •ˆ˜๋กœ —ญ–ด ๋„ค๋Š” ฒƒด๋‹ค.

~cpp 
    class BookEntry{
    public:
        ...
    private:
        ...
        void cleanup(); // ฒƒฒด๋ฅผ ‚ญ œ•˜๋Š”ฑธ ๋ฌถ€ฒƒ
    };

~cpp 
    BookEntry::BookEntry(const string& name,
                         const string& address,
                         const string& imageFileName,
                         const string& audioClipFileName)
    :theName(name), theAddress(address), theImage(0), theAudioClip(0)
    {
        try{
            ...
        }
        catch (...){
            cleanup();
            throw;
        }
    }
    BookEntry::~BookEntry{
        cleanup();
    }

ž  œ นจ๋—•ฒฐ ๋œ ฒƒœผ๋กœ ๋ณดธ๋‹ค. •˜ง€๋งŒ ด๋ฒˆ—๋Š” ด๋Ÿฐ ฒฝšฐ๋ฅผ ƒ ••ด ๋ณดž

~cpp 
    class BookEntry{
    public :
        ...
    private:
        ...
        Image * const theImage;
        AudioClip * const theAudioClip;
    }

ด๋Ÿฐ const ฌ„˜ ฒฝšฐ—๋Š” ๋ฐ˜๋“œ‹œ ดˆธฐ™” ๋ฆฌŠคŠธ๋ฅผ šฉ•˜—ฌ ž๋ฅผ ดˆธฐ™” •ฃผ–ด••˜๋Š” ฒฝšฐด๋‹ค.

~cpp 
    class BookEntry{
    public :
        ...
    private:
        ...
        Image * initImage(const string& imageFileName);
        AudioClip * initAudioClip(const string& theAudioClip);
    }

    BookEntry::BookEntry(const string& name,
                         const string& address,
                         const string& imageFileName,
                         const string& audioClipFileName)
    :theName(name), theAddress(address), 
     theImage(initImage(imageFileName)), theAudioClip(initAudioClip(AudioCilpFileName))
    {}
    // theImage๋Š” ฐ€žฅ ˜Œ ดˆธฐ™” ๋˜–ด„œ ž›„ธ๋Š” ฒƒ—๋Œ€•œ ฑฑ •—†๋‹ค. ธ๋ž˜„œ •ด๋‹†ŒŠค—„œ 
    // ˜ˆ™ธ˜๋ฆฌ๋ฅผ ƒ๋žต•˜˜€๋‹ค.
   Image * initImage(const string& imageFileName)
    {
        if (imageFileName != "") return new Image(imageFileName);
        else return 0;
    }
    // theAudioClip๋Š” ๋‘๋ฒˆงธ๋กœ ดˆธฐ™” ๋˜ธฐ ๋•Œ๋ฌธ—, ˜ˆ™ธ˜ ๋ฐœƒฒฝšฐ ด๋ฏธ • ‹น๋˜–ด„ theImage˜ ž›„ 
    //  • œ•ฃผ๋Š” ˜ˆ™ธ ˜๋ฆฌฐ€ •„š”•˜‹ค. 
    AudioClip * initAudioClip(const string& theAudioClip)
    {
        try{
            if (adioClipFileName != ""){
                return new AudioClip(audioClipFileName);
            }
            else return 0;
        }
        catch ( ... ){
            delete theImage;
            throw;
        }
    }
ด๋Ÿฐ •ฒฐ ๋ฐฉ๋ฒ•€ ˜ฌ๋ฐ”๋ฅด๋‹•˜ง€๋งŒ,  „— –ธธ‰•œ ฒƒณผ ฐ™†ŒŠค ‚ฌ›„ ด€๋ฆฌ™€ ˜„žฌ †ŒŠค žฒด๋„ ๋งŽง€ €๋ถ„•˜‹

ธ๋ž˜„œ ๋” ‹€ ๋ฐฉ๋ฒ•€ Item 9—„œ –ธธ‰•œ ๋ฐฉ๋ฒ•„ ‚ฌšฉ•˜๋Š” ฒƒด๋‹ค.
~cpp 
    class BookEntry{
    pubcli:
    ...
    private:
    ...
    const auto_ptr<Image> theImage;
    const auto_ptr<AudioClip> theAudioClip;
ธ๋ฆฌ  ƒ„ž˜ ฝ”๋“œ๋ฅผ ด๋ ‡ฒŒ •œ‹ค.
~cpp 
    BookEntry::BookEntry(const string& name,
                         const string& address,
                         const string& imageFileName,
                         const string& audioClipFileName)
    :theName(name), theAddress(address),
     theImage(imageFileName != "" ? new Image(imageFileName) : 0),
     theAudioClip( audioClipFileName != "" ? new AudioClip(audioClipFileName):0)
      {}

ด๋ ‡ฒŒ ๋””ž• ฒฝšฐ ŒŒดด๋Š” ž๋™œผ๋กœ ด๋ฃจ–ด „‹ค. ธ๋Ÿฌ๋ฏ€๋กœ ŒŒดดž๋Š”
~cpp 
    BookEntry::~BookEntry()
    {}
ด๋ ‡ฒŒ •„๋ฌดฒƒ๋„ •ฃผง€ •Š•„๋„ ฒดฐ€ ฐ™ŒŒดด๋˜  ๋ฆฌ†ŒŠคฐ€ ƒˆ๋Š” ฒƒ„ ๋ฐฉง€ • ˆ˜ žˆ๋‹ค.

1.3. Item 11: Prevent exception from leaving destuctors.

  • Item 11: ŒŒดดž๋กœ ๋ถ€„˜ ˜ˆ™ธ ˜๋ฆฌ๋ฅผ ๋ง‰•„ผ.

ŒŒดดž ˜œ€ ๋‘ฐ€ง€˜ ฒฝšฐฐ€ žˆ๋‹ค. ฒซ๋ฒˆงธฐ€ 'normal'ƒƒœ๋กœ ฒดฐ€ ŒŒดด๋˜–ด งˆ๋•Œ๋กœ ฒƒ€ ๋ณด†ต ๋ช…‹œ œผ๋กœ deleteฐ€ ๋ถˆ๋ฆฐ๋‹ค. ๋‘๋ฒˆงธ๋Š” ˜ˆ™ธฐ€  „‹ฌ๋˜๋ฉด„œ Šคƒ’€๋ฆด๋•Œ ˜ˆ™ธ ˜๋ฆฌ‹œ(exception-handling) ฒดฐ€ ŒŒดด๋˜–ด ง€๋Š” ฒฝšฐฐ€ žˆ๋‹ค.

‹Œ ˜ˆ œ๋Š” online ปด“จ„„…˜„ œ„•œ Session ด๋ž˜Šค๋ฅผ ƒฐ•ด ๋ณธ ฒƒด๋‹ค. ฐ „…˜ ฒด๋“ค€ ƒ„ณผ ŒŒ๋˜๋œ ๋‚ œ๋ฅผ ธฐ๋ก••ผ๋งŒ •œ‹ค.
~cpp 
    class Session{
    public:
        Session();
        ~Session();
        ...
    private:
        static void logCreation(Session *objAddr);
        static void logDestruction(Session *objAddr);
    };

‹Œณผ ฐ™ŒŒดดž—„œ ๋กœธ ๋ฐ„ฐ๋ฅผ ๋‚จธด๋‹ค.
~cpp 
    Session::~Session()
    {
        logDestruction(this);
    }

ž ฑด œฐฎ•„ ๋ณดธ๋‹ค. •˜ง€๋งŒ  € logDestructionƒ—„œ ˜ˆ™ธฐ€ ๋ฐœƒ•œ‹ค๋ฉด –ดฉŒฒŒ • ฒƒฐ€? •ด๋‹†ŒŠค๋Š” Session˜ ŒŒดดž •ˆ—„œ๋Š” ˜ˆ™ธ๋ฅผ žกง€ ๋ชป•œ‹ค. ธ๋ž˜„œ •ด๋‹ŒŒดดž๋ฅผ ˜œ•œ ž—ฒŒ ˜ˆ™ธ๋ฅผ ๋˜„( „‹•œ)๋‹ค. ธ๋ ‡ง€๋งŒ ๋‹ค๋ฅธ —๋Ÿฌ๋“คด ๋˜ „ ƒ™ฉ—„œ ŒŒดดžฐ€ ŠคŠค๋กœ ž‹ „ ๋ถ€๋ฅธฑฐ๋ผ๋ฉด •ˆ˜˜ ข…๋ฃŒฐ€ ž๋™œผ๋กœ ด๋ฃจ–ดง€ธฐ๋ฅผ ›•  ฒƒด๋‹ค. ธ๋ฆฌ ‹‹ ˜ ”„๋กœธ๋žจ€ ฏค—„œ ๋จธถ”–ด ๋ฒ„๋ฆด ฒƒด๋‹ค. -•„ƒ•˜ตฐ, •”Šผ ๋‹ค๋ฅธ ˜ˆ™ธ ˜๋ฆฌ‹œ— „…˜ ŒŒดดž ๋กœ‹œ ˜ˆ™ธฐ€ ๋ฐœƒ•œ‹ค๋ฉด ”„๋กœธ๋žจด ๋ฉˆ˜‹ค๋Š” †Œ๋ฆฌ๋‹ค.

•„๋งˆ ๋Œ€๋‹ˆ˜˜ ‚ฌ๋žŒ๋“คด๋Ÿฐ ƒƒœ๋กœ ๋น ง€๋Š”ฑธ ›•˜ง€ •Š„ ฒƒด๋‹ค. Session ฒด˜ ŒŒดด๋Š” ธฐ๋ก๋˜ง€ •Š„ ƒœ‹ˆนŒ. ฑด ƒ๋‹žˆ ปค๋‹ค๋ž€ ๋ฌธ œด๋‹ธ๋Ÿฌ๋‚˜ ฒƒข€๋” ‹•œ ๋ฌธ œ๋ฅผ œ ๋ฐœ•˜๋Š”ฑด ”„๋กœธ๋žจด ๋” „• ˆ˜ —†„•Œ ฒƒด๋‹ค. ธ๋ž˜„œ Session˜ ŒŒดดž—„œ˜ ˜ˆ™ธ  „‹„ ๋ง‰•„••œ‹ค. ๋ฐฉ๋ฒ•€ •˜๋‚˜ try-catch๋กœ žก•„ ๋ฒ„๋ฆฌ๋Š” ฒƒด๋‹ค.
~cpp 
    Session::~Sessioni()
    {
        try{
            logDestruction(this);
        }
        catch ( ... ){
            cerr << "•ด๋‹ฃผ†Œ—„œ „…˜ ฒด˜ ŒŒดดธฐ๋กด ๋˜ง€ •ŠŠต๋‹ˆ๋‹ค."
                 << "-ฃผ†Œ:"
                 << this << ".\n";
    }       
•˜ง€๋งŒ ฒƒ๋„ ›๋ž˜˜ ฝ”๋“œ๋ณด๋‹•ˆ „•  ฒƒ—†๋‹ค. ๋งŒ•ฝ operator<< ๋ถ€๋ฅผ๋•Œ exception์ด ๋ฐœ์ƒํ•œ๋‹ค๋ฉด ํŒŒ๊ดด์ž๊ฐ€ ๋˜์ง€๋Š” exception์œผ๋กœ ๋‹ค์‹œ ์šฐ๋ฆฌ๊ฐ€ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” ์›์ ์œผ๋กœ ๋Œ์•„๊ฐ€ ๋ฒ„๋ฆฐ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด
~cpp 
    Session::~Sessioni()
    {
        try{
            logDestruction(this);
        }
        catch ( ... ){ }       
ด๋ ‡ฒŒ •„๋ฌด๋Ÿฐ ˜๋ฆฌ๋ฅผ •˜ง€ •Š๋Š”๋‹ค๋ฉด logDestuction—„œ ๋ฐœƒ•œ ˜ˆ™ธฐ€  „‹ฌ๋˜๋Š”ฑธ ๋ง‰  ”„๋กœธ๋žจ ‘ง€๋ฅผ œ„•˜—ฌ Šคƒ’€๋ ค๋‚˜ฐ€๋Š”ฑธ ๋ง‰„ˆ˜๋Š” žˆ„ ฒƒด๋‹ค.

•˜ง€๋งŒ ด๋Ÿฐ ๋‘๋ฒˆงธ˜ ƒฐ๋„ ŒŒดดž—„œ ๋ฐœƒ•˜๋Š” ๋ชจ๋“  —๋Ÿฌ๋ฅผ ๋ง‰•„ ๋ฒ„๋ฆฌ  ธ๋ƒฅ ๋„˜–ดฐ€ ๋ฒ„๋ฆฐ๋‹ค๋Š” ๋‹ žˆ๋‹ค.
๋ฐ‘˜ ฝ”๋“œ๋Š” DB˜ Šธ๋žœ …˜„ šฉ•„œ —๋Ÿฌ๋ฅผ ˜๋ฆฌ•˜๋Š” ๋ชจŠตด๋‹ค.
~cpp 
    Session::Session()
    {
        logCreation(this);
        startTransaction();
    }
    Session::~Session()
    {
        logDestruction(this);
        endTransaction();
    }
ด๋Ÿด ฒฝšฐ—๋Š” Session˜ ŒŒดดž—ฒŒ ๋ฌธ œ๋ฅผ  œฑฐ•˜๋Š” ๋ช…๋ „‹‹œ ๋‚ด๋ฆดˆ˜ žˆ๋”ฐ •˜ง€๋งŒ endTransaction˜ˆ™ธ๋ฅผ ๋ฐœƒžˆ‚จ๋‹ค๋ฉด ๋‹‹œ try-catch๋ฌธœผ๋กœ ๋Œ•„ ฐˆˆ˜ ๋ฐ–— —†๋‹ค.

๋‚œ œ‹ค ๋‚œ œ

1.4. Item 12: Understand how throwing an exception differs from passing a parameter or calling a virtual function

  • Item 12: ฐ€ƒ •ˆ˜ ๋ถ€๋ฅดธฐ๋‚˜, ž  „‹ฌ๋กœ ˜๋ฆฌ™€ ˜ˆ™ธ „‹˜ ๋ฐฉ๋ฒ•˜ ฐจ „ ••˜ผ.

‹Œ˜ ฐ€ƒ•ˆ˜˜ „ –ธณผ ฐ™ด ๋‹‹ € catch ตฌ๋ฌธ—„œ๋„ ๋น„Š•˜ฒŒ ž๋“ค„„„ˆ˜ žˆ๋‹ค.
~cpp 
    class Widget { ... };

    void f1(Widget w);
    void f2(Widget& w);
    void f3(const Widget w);
    void f4(Widget *pw);
    void f5(const Widget *pw);

    catch (Widget w) ...
    catch (Widget& w) ...
    catch (const Widget w) ...
    catch (Widget *pw) ...
    catch (const Widget *pw) ...

ธ๋ž˜„œ •„๋งˆ •ˆ˜˜œ—„œ ž  „‹ณผ ณผ ˜ˆ™ธฐ€  „‹ฌ๋˜๋Š” ฒƒธฐ๋ณธ œผ๋กœ ฐ™€ฒƒด๋  ƒฐ • ง€๋„ ๋ชจ๋ฅธ๋‹ค. ๋ถ„๋ช… ๋‘˜€ ๋น„Š•œ ๋ฉดžˆ๋‹ค. •˜ง€๋งŒ ‘š”•œ ฐจ  —ญ‹œ กดžฌ •œ‹ค.

ž, ๋น„Š•œ ๋ฉด€ –ธธ‰•ด๋ณด๋ฉด, •ˆ˜ ˜ˆ™ธ ๋ชจ๋‘ — ž๋ฅผ  „‹• •Œ „ฐ€ง€๋กœ  „‹• ˆ˜ žˆ๋‹ค. ฐ’(by value)ด๋ƒ ฐธกฐ(by reference)๋ƒ, ˜€ ฌ„ฐ(by pointer)๋ƒ ๋ฐ”๋กœ ฒƒด๋‹ค. •˜ง€๋งŒ •ˆ˜™€ ˜ˆ™ธ—„œ˜ ž˜  „‹ฌ ๋ฐฉ‹€ ตฌ๋™ ๋ฐฉ๋ฒ•—„œ ฒฐ • ฐจ „ ๋ณดธ๋‹ค. ด๋Ÿฐ ฐจ € ๋‹‹ •ˆ˜๋ฅผ ˜œ• •Œ œข… œผ๋กœ ๋ฐ˜™˜๋˜๋Š” ฐ’(returns)•ด๋‹•ˆ˜๋ฅผ ๋ถ€๋ฅด๋Š” œ„˜๋กœ ฐ€ง€๋งŒ, ˜ˆ™ธ˜ ฒฝšฐ— throw˜ œ„˜™€ return˜ œ„˜ฐ€ ๋‹ค๋ฅด๋‹ค๋Š”  —„œ ธฐ•œ‹ค.

‹Œ •ˆ˜—„œ Widget˜ ž  „‹ณผ ˜ˆ™ธ—„œ˜  „‹„ ƒฐ•ด ๋ณดž.
~cpp 
    // †ŒŠค๋Š” œ„˜ Widget˜ ™˜ด๋  ƒฐ•˜๋ฉด ๋ฌด๋ฆฌ —† ‹ค.
    istream operator>>(istream& s, Widget& w);
    void passAndThrowWidget()
    {
        Widget localWidget;
        cin >> localWidget;
        throw localWidget;
    }

localWidgetด operator>> ๋กœ  „‹ฌ๋ •Œ๋Š” ๋ณต‚ฌ˜ ณผ •–ด๋‚˜ง€ •Š๋Š”๋‹ค. ๋Œ€‹  operator>> •ˆ˜ ฐธกฐ wฐ€ localWidgetณผ ๋ฌถ—ฌ„œ –ด๋– •œ ณผ •„ ˜๋ฆฌ•˜ฒŒ ๋œ‹ค. •˜ง€๋งŒ ˜ˆ™ธ˜ ˜๋ฆฌ—„œ localWidget€ ข€ ๋‹ค๋ฅธ •ธฐ๋ฅผ ๋งŒ๋“ค–ด ๋‚˜„‹ค. ˜ˆ™ธฐ€ ฐ’ด๋‚˜, ฐธกฐ๋ฅผ žก๋“  žกง€(pointer๋Š” žกง€ ๋ชป•œ‹ค.) •Š๋“  ƒด€ —†ด localWidget˜ ‚ฌ๋ณธด ๋งŒ๋“ค–ดง€ , ‚ฌ๋ณธ€ catch๋กœ  €๋‚Ÿใ„น ๋œ‹ค. ™œ๋ƒ•˜๋ฉด passAndThrowWidget˜ ˜—ญ„ ๋ฒ—–ด๋‚˜๋ฉด localWidget˜ ŒŒดดž˜ ˜œด ๋˜ธฐ ๋•Œ๋ฌธ— ๋ฐ˜๋“œ‹œ ด๋ ‡ฒŒ ๋˜–ด••œ‹ค. ฒƒ€ C++ —„œ ˜ˆ™ธ๋Š” •ƒ ‚ฌ๋ณธœผ๋กœ  „‹ฌ๋œ‹ค๋Š” œ ฐ€ ๋œ‹ค.

ด๋Ÿฐ ๋ณต‚ฌ˜ ณผ •€ •„๋ฌด๋ฆฌ ŒŒดด˜ œ„—˜—†๋Š” ˜ˆ™ธ๋ผ๋„ ด๋ฃจ–ด „‹ค. ˜ˆ๋ฅผ ๋“คž๋ฉด

~cpp 
    void passAndThrowWidget()
    {
        static Widget localWidget;
        cin >> localWidget;
        throw localWidget;
    }

•ด๋‹‚ฌ๋ณธ€ ตฌง€ ๋ณต‚ฌ•  •„š”ฐ€ —†„ ฒƒด๋‹ค. •˜ง€๋งŒ catch ๋Š” ๋ณต‚ฌ•ด ๋‚˜ฐ€  ธ๋ž˜•ผ๋งŒ catch —„œ localWidget˜ ‚ฌ๋ณธ„ Žธ‘•„œ šฉ• ˆ˜ žˆ๋‹ค. ด๋Ÿฌ•œ ๋ณต‚ฌ˜ œน™€ •ˆ˜  „‹ณผ ˜ˆ™ธ ž  „‹˜ ฐจ „ „ค๋ช…•ค€๋‹ค.

ฒดฐ€ ˜ˆ™ธ๋ฅผ œ„•˜—ฌ ๋ณต‚ฌฐ€ ๋ •Œ ๋ณต‚ฌ๋Š” •ด๋‹ฒด˜ ๋ณต‚ฌƒ„ž(copy constructor)— ˜•˜—ฌ ˆ˜–‰ ๋œ‹ค. ด ๋ณต‚ฌƒ„ž๋Š” ฒด˜ dynamic˜••„‹Œ static ˜•— •ด๋‹•˜๋Š” ด๋ž˜Šค‘ •˜๋‚˜ด๋‹ค. œ๋…˜ ™•„ œ„•œ„ †ŒŠค˜ ˆ˜ • ๋ฒ„ „„ ƒฐ•ด ๋ณดž
~cpp 
class Widget { ...}
class SpecialWidget: public Widget { ... };
void passAndThrowWidget()
{
    SpecialWidget localSpecialWidget;
    ...
    Widget& rw = localSpecialWidget;
    throw rw;                           // rw˜ ˜• ฆ‰ Widget˜ ๋ณต‚ฌƒ„žฐ€ ž‘๋™•˜—ฌ ๋ณต‚ฌ•˜ˆ™ธ๋ฅผ ๋ฐœƒ‹œ‚จ๋‹ค.
}

‹Œ˜ ฒฝšฐ passAndThrowWidget ด ๋˜ง€๋Š”ฑด Widget ด๋‹ค. œ„—„œ –ธธ‰–ˆ๋“ฏด static typeœผ๋กœ ˜ˆ™ธ๋Š”  „‹ฌ๋œ‹ค. ปดŒŒผ๋Ÿฌ๋Š” rwฐ€ SpecialWidgetœผ๋กœ˜ ๋™ž‘„  „˜€ ƒฐ•˜ง€ •Š๋Š”๋‹ค.

˜ˆ™ธ˜๋ฆฌ‹œ— ๋‹ค๋ฅธ ฒด˜ ‚ฌ๋ณธ „‹ฌ ๋œ‹ค๋Š”  € ˜ˆ™ธฐ€ „†  „‹ฌ(ผ ธ๋‚˜ฐˆ๋•Œ,propagate)—๋„ •œฐ€ง€˜   ‚ฌ•ด ๋ฐœƒ•œ‹ค. ๋‹Œ˜‘ฐ€ง€˜ catch ๋ธ”๋Ÿญ€ ฐจ žˆ๋‹ค. •˜ง€๋งŒ ™ธฒฌƒ ฐ™€ —ญ• „ •œ‹ค.
~cpp 
    catch (Widget& w)
    {
        ...
        throw;              // •ด๋‹ฒด๋ฅผ ๋‹‹œ ๋ณต‚ฌ•˜ง€ •Š  ๋˜ง€๋ฉฐ, •ด๋‹˜ˆ™ธ๋ฅผ propagete •œ‹ค. 
    }
    catch (Widget& w)
    {
        ...
        throw w;            // •ด๋‹ฒด๋ฅผ ๋‹‹œ ๋ณต‚ฌ•„œ ‚ฌ๋ณธ„ propagate•œ‹ค.
    }
ฃผ„— ๋˜–ด žˆ๋Š”๋ฐ๋กœ, ƒฐ•ด ๋ณด๋ผ. throwฐ€ ๋ณต‚ฌƒ„ž๋ฅผ ˜œ•˜ง€ •Š•„„œ šจœ ด๋‹ค. ธ๋ฆฌ  throw๋Š” –ด๋– •œ ˜•ด๋“  ˜ˆ™ธ๋ฅผ  „‹•œ๋Š”๋ฐ ƒด€•˜ง€ •Š๋Š”๋‹ค. •˜ง€๋งŒ, ‚ฌ‹˜ˆ™ธžฒดฐ€ ˜•— ๋งžฒŒ ๋˜ ง€๋ฏ€๋กœ ฑฑ •—†๋‹ค. •˜ง€๋งŒ catch๋ฌธ—„œ ˜ˆ™ธ๋ฅผ ๋˜ง€๋Š” ฒด˜ ˜•ƒœ๋ฅผ ๋ฐ”ฟ€ •„š”„žˆ„•Œ ›„ž๋ฅผ ‚ฌšฉ•• ‹ค.

ž ธ๋Ÿผ ๋‹Œ˜ „ฐ€ง€ catch— ด€•„œ ‹œ—˜•ด ๋ณดž. passAndThrowWidget—„œ ๋ฐœƒ•œ ˜ˆ™ธ๋Š” ๋‹Œ˜ „ฐ€ง€˜ ฒฝšฐ๋กœ žก„ˆ˜ žˆ๋Š”ฑธ ˜ˆƒ• ˆ˜ žˆ๋‹ค.
~cpp 
catch (Widget w) ...        // ฐ’œผ๋กœ  „‹ฌ

catch (Widget& w) ...       // ฐธกฐ  „‹ฌ

catch (const Widget& w) ... // ƒˆ˜ ฐธกฐ๋กœ  „‹
 „‹ฌ๋œ ฒด๋Š” „‹žˆ ฐธกฐ๋กœ žก„ˆ˜ žˆ๋‹ค;ฒƒ€ ƒˆ˜ ฐธกฐ๋กœ  „‹ฌ๋  •„š”„€ —†๋‹ค. ธ๋Ÿฌ๋‚˜ ƒˆ˜ ฐธกฐฐ€ •„‹Œ  „‹ž„‹œ ฒด๋“ค€ •ˆ˜๋ฅผ ๋ถ€๋ฅด๋Š”ฑธ —ˆšฉ•˜ง€ •Š๋Š”๋‹ค.

ธ๋Ÿผ ด๋“ค˜ ฐจ „ ‚ดŽด๋ณด  ˜ˆ™ธ ฒด๋“ค„ ๋ฆฌ„•ด ๋ณดž.

~cpp 
    catch (Widget w) ...    // ฐ’œผ๋กœ  „‹
ด๋ ‡ฒŒ ฐ’œผ๋กœ  „‹•˜๋ฉด ๋‘๋ฒˆ˜ ๋ณต‚ฌฐ€ –ด๋‚˜๋Š”ฑธ ˜ˆƒ• ˆ˜ žˆ๋‹ค. throw‹œ •œ๋ฒˆ catch‹œ •œ๋ฒˆ ok? ๋น„šจœด๋‹ค.

ฐธกฐ๋กœ  „‹• •Œ ˜ˆƒ•ด ๋ณดž
~cpp 
    catch (Widget& w) ...           // ฐธกฐ  „‹ฌ.
    catch (const Widget& w) ...     // ƒˆ˜-ฐธกฐ  „‹
šฐ๋ฆฌ๋Š” ง€ธˆนŒง€ ๋ณต‚ฌ— ˜•œ ง€๋ถˆ„ ƒฐ• ˆ˜ žˆ๋Š”๋ฐ ฐธกฐ˜  „‹€ ๋ฐ˜๋Œ€๋กœ ๋ณต‚ฌ•˜๋Š” ž‘—…—†๋‹ค. ฆ‰, •œ๋ฒˆ˜ ๋ณต‚ฌ ›„ „† ฐ™€ ฒด๋ฅผ ‚ฌšฉ•˜ฒŒ ๋˜๋Š” …ˆด๋‹ค.

šฐ๋ฆฐ •„ง ฌ„ „‹— ˜•œ ฑธ ˜๋…ผ•˜ง€ •Š•˜‹ค. •˜ง€๋งŒ ฌ„ฐ๋ฅผ šฉ•˜ˆ™ธ๋ฅผ ๋˜ง€( „‹ฌ:throw)•˜๋Š” ฒƒ€ •ˆ˜ƒ—„œ ฌ„ฐ๋ฅผ  „‹ฌ(pass)•˜๋Š” ฒƒณผ๋Š” ๋‹ค๋ฅธฑธ •Œˆ˜ ž‡„ ฒƒด๋‹ค. ฆ‰, ฌ„˜ ๋ณต‚ฌ๋ณธด๋™•˜๋Š”๋ฐ, ด๋ ‡ฒŒ ๋˜๋ฉด pointer๋ฅผ  „‹•˜๋Š” ชฝ˜ ˜—ญ—„œ throw— ˜•Š€–ด ๋‚˜ฐ€๋ฉด ฌ„ฐ€ ฐ€๋ฆฌ‚ค  žˆ๋Š” ฒด๋Š” †Œ๋ฉธ๋˜๋ฏ€๋กœ ฌ„— ˜•œ ˜ˆ™ธ  „‹ฌ(๋˜ง€๋Š”ฒƒ:throw)๋Š” ”ผ•••œ‹ค. ( „—ญ˜ static ฒด˜ ฌ„ฐ๋ผ๋ฉด •ธฐ๋Š” ๋‹ฌ๋„‹ค. ๋’ค— ๋‹ค๋ฃฌ๋‹ค.)

ž ธ๋Ÿผ ˜ˆ™ธ๋ฅผ ๋˜งˆ๋•Œ˜ ˜•— ด€•œ ฃผ˜๋ฅผ ‚ดŽด ๋ณดž. C++˜ •”‹œ  ๋ณ€™˜— ˜•œ ฒƒธ ๋ฌธ œ˜ ๋ฐœ‹ธ๋ฐ, ฝ”๋“œ๋ฅผ ๋ณดž ‘œค€ ˆ˜•™ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ—„œ
~cpp 
    double sqrt(double);
๋ฅผ ด๋ ‡ฒŒ ‚ฌšฉ • ˆ˜ žˆ๋‹ค.
~cpp 
    int i;
    double sqrtOfi = sqrt(i);
Item 5—๋„ –ธธ‰๋˜–ด žˆ๋“ฏด C++ƒ—„œ˜ •”‹œ  ๋ณ€™˜€ ‘ ๋ฒ”œ„•˜‹ค. i˜•˜ double๋ณ€™˜€ ฐ€๋ฟ? •˜‹ค. •˜ง€๋งŒ ๋‹Œ„ ๋ณดž
~cpp 
    void f (int value)
    {
        try {
            if (someFunction() ) {      // someFunction()ฐธด๋ฉด int˜•˜ ๋ณ€ˆ˜๋ฅผ ˜ˆ™ธ๋กœ ๋˜„‹ค.
                throw value;
            }
            ...
        }
        catch (double d) {      // •ด๋‹•ธ๋“ค€ doubleผ๋•Œ๋งŒ ˜ˆ™ธ๋ฅผ žก„ˆ˜ žˆ๋‹ค. ธ๋Ÿผ value๋ฅผ ๋˜ง€๋Š”
            ...                 // try—„œ˜ ˜ˆ™ธ๋Š”  ˆ๋Œ€๋กœ žกžˆง€ •Š๋Š”๋‹ค. ˜๋„•œ ๋ฐ”ฐ€ •„‹ˆ๋ฆฌ๋ผ.
        }
        ...
    }
ด๋Ÿฐ ‚ฌ•„ œ ˜ •••œ‹ค. ˜ˆ™ธ—„œ๋Š” •”‹œ  ๋ณ€™˜„ ƒฐ•˜ง€ •Š๋Š”๋‹ค.

ธ๋Ÿผ ˜ˆ™ธ˜ ๋ณ€™˜—๋Š” ฌฒŒ ๋‘ฐ€ง€˜ ƒฐ•   žˆ๋Š”๋ฐ. ฒซ๋ฒˆงธฐ€ ƒ† ด€„(˜ˆ™ธ ƒ˜) ด๋‹ค. ˜ˆ™ธ—„œ๋Š” •œ ˜ˆ™ธ ฒด—„œ ŒŒƒ๋œ‹ค๋ฅธ ˜ˆ™ธฒด๋“ค„ žก๋Š”ฒƒฐ€๋Šฅ•œ๋ฐ ˜ˆ๋ฅผ๋“ค–ด„œ ‘œค€ C++ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ—„œ˜ ˜ˆ™ธ ƒ†๋„๋Š” ด๋ ‡ฒŒ ตฌ„ฑ๋˜—ˆ๋‹ค. (๋ชจ๋“  ˜ˆ™ธฐ€ ๋‚˜™”๋Š”ง€๋Š” ๋ชจ๋ฅด ‹ค.)
~cpp 
    exception 
        |
        +-logic_error
        |   |
        |   +-domain_error
        |   +-invalid_argument
        |   +-length_error
        |
        +-runtime_error
            |
            +-range_error
            +-underflow_error
            +-overflow_error

catch—„œ ๋ถ€๋ชจ ฒด๋กœ žกœผ๋ฉด ž‹ ฒด˜ ˜ˆ™ธ๋“คด ๋‹žกžˆ๋Š” ‹ด๋‹ค .˜ˆ๋ฅผ ๋“คž๋ฉด
~cpp 
catch (runtime_error) ...           // ด๋ ‡ฒŒ „ –ธ•˜๋ฉด runtime_errorž‹ธ
catch (runtime_error&) ...          // range_error, underflow_error
catch (const runtime_error&) ...    // overflow_errorด ๋‹žกžˆ๋Š” ฑฐ๋‹ค.


catch (runtime_error*) ...          // ด๋ ‡ฒŒ •˜๋ฉด runtime_error*
catch (const runtime_error*) ...    // range_error*, underflow_error*, overflow_error* œผ๋กœ žกžˆ๋Š” ฒƒด๋‹ค.

‘๋ฒˆงธ˜ ƒฐ•   € ๋ชจ๋“  ˜ˆ™ธ๋ฅผ žก  ‹œผ๋ฉด
~cpp 
    catch (const void*) ...
ด๋ ‡ฒŒ •˜๋ฉด –ด๋– •œ ฌ„ฐ type๋ผ๋„ žก„ ฒƒด๋‹ค.

๋งˆง€๋ง‰œผ๋กœ ž ๋„˜ธฐธฐ™€ ˜ˆ™ธ  „‹ฌ(๋˜ง€ธฐ:throw)˜‹ค๋ฅธ  € catch ตฌ๋ฌธ€ •ƒ catchฐ€ “ฐ—ฌ„ ˆœ„œ๋Œ€๋กœ (in the order of their appearance) ตฌ๋™๋œ‹ค๋Š”  ด๋‹ค. (˜–ด ตฌ๋ฌธ„ ฐธกฐ•˜‹œธธ) ๋งƒ•˜‹ค. ธ๋ƒฅ ๋‹Œ ˜ˆ œ๋ฅผ ๋ณดž

~cpp 
    try{
        ...
    }
    catch (logic_error& ex) {       // —ฌธฐ—„œ ๋ชจ๋“  logic—๋Ÿฌฐ€ žกžŒ๋‹ค.
        ...
    }
    catch (invalid_argument & ex){  // ด ๋ฌธ€ ž‘๋™„ •˜ง€ •Š๋Š”๋‹ค. œ„˜ catchตฌ๋ถ„—„œ ด๋ฏธ žก•„ ๋ฒ„๋ฆฐ๋‹ค.
        ...
    }

๋ฐ˜๋Œ€๋กœ ฐ€ƒ•ˆ˜๋ฅผ ๋ถ€๋ฅผ๋•Œ –ด๋‚˜๋Š”žˆ๋‹ค. ๋‹‹ ฐ€ƒ•ˆ˜๋ฅผ ˜œ•˜๋ฉด •ˆ˜๋Š” •ด๋‹ฒด˜ ฐ€žฅ •ฉ๋‹•œ •ˆ˜๋ฅผ dynamicœผ๋กœ ฐพ•„๋‚ธ๋‹ค. ฒƒ€ œ ๋กœ  ••œ ฒƒ(best fit)„ ˜๋ฏธ•˜ง€ ฐ€žฅ ˜Œ— ฐพ•„ ง€๋Š” ฒƒ(first fit)„ ˜๋ฏธ•˜๋Š” ฒƒ•„‹ˆ๋‹ค. œ„˜ †ŒŠค๋ฅผ ๋ฐ˜๋Œ€๋กœ •œ‹ค๋ฉด

~cpp 
    try{
        ...
    }
    catch (invalid_argument & ex){  // invalid_argument ˜ˆ™ธ๋Š” ณณ—„œ žกžŒ๋‹ค.
        ...
    }
    catch (logic_error& ex) {       // —ฌธฐ„œ ๋ชจ๋“ ‹ค๋ฅธ logic_error ด€๋ € ณณ—„œ žกžŒ๋‹ค.
        ...
    }
ด๋ ‡ฒŒ ๋Œ•„ฐ€๋Š” ฑฐ๋‹ค.

žž  •๋ฆฌ
  • ฒซงธ๋กœ ˜ˆ™ธ ฒด๋Š” •ƒ ๋ณต‚ฌ ๋œ‹ค.
  • ‘˜งธ๋กœ ๋˜ €ง€๋Š” ฒด๋Š” •ˆ˜๋กœ  „‹ฌ๋ •Œ ๋น„•˜—ฌ ˜•— ๋Œ€•œ ๋ณ€™˜˜•— ˜–ฅ ๋ฐ›ธฐ ‰ฝ๋‹ค.
    ˜ˆ™ธ ฒด๋Š” ƒ†— œน™„ ๋”ฐ๋ฅธ๋‹ค. („ค๋ช…„ ๋ณด‹œธธ)
  • …‹งธ๋กœ †ŒŠค ฝ”๋“œ— ๋‚˜ƒ€๋‚˜๋Š” ˆœ„œ๋Œ€๋กœ ˜ˆ™ธ๋Š” žกžŒ๋‹ค.

1.5. Item 13: Catch exception by reference

  • Item 13: ˜ˆ™ธ๋Š” ฐธกฐ(reference)๋กœ žก•„ผ.

catch ตฌ๋ฌธ„ ‚ฌšฉ• •Œ •ด๋‹ตฌ๋ฌธ„ †ต•„œ  „‹ฌ๋ฐ›€ ˜ˆ™ธ ฒด๋“ค„ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•„ ž˜•Œ•„••œ‹ค. ๋‹‹ € „ฐ€ง€˜ „ ƒ„ • ˆ˜ žˆ๋‹ค. ๋ฐ”๋กœ  „ Item 12—„œ –ธธ‰•œ ฒƒ˜๋Ÿผ ฐ’(by value), ฐธกฐ(by reference), ฌ„ฐ(by pointer)ด๋ ‡ฒŒ „ฐ€ง€  •๋„ฐ€ ๋ ฒƒด๋‹ค.

ž, ๋จผ € pointer(by pointer)— ด€•œ  „‹„ ƒฐ•ด ๋ณดž. ด๋ก  œผ๋กœ ด ๋ฐฉ๋ฒ•€ throwœ„˜—„œ catchตฌ๋ถ„œผ๋กœ ˜ˆ™ธ๋ฅผ Šน๋ณ„•œ ๋ณ€™” —†ด ๋А๋ฆฐ ”„๋กœธ๋žจ ˆ˜–‰ ƒƒœ—„œ  „‹•˜ธฐ— ฐ€žฅ ‹€ ๋ฐฉ๋ฒ•ด๋‹ค. œ ๋Š” ฌ„˜  „‹€ •ด๋‹˜ˆ™ธ ฒดฐ€ ๋ณต‚ฌ๋˜๋Š” —†ฌ„ฐ’๋งŒ  „‹ฌ๋˜๋Š” ๋ฐฉ๋ฒ•๋งŒ„ •••˜ธฐ ๋•Œ๋ฌธด๋‹ค. ๋งข€ ƒ•œ๋ฐ ˜ˆ™ธ๋ฅผ ๋ณด๋ฉด„œ „ค๋ช…•œ‹ค.

Item 12—„œ –ธธ‰•œฒƒณผ ฐ™˜ˆ™ธ๋Š” ๋ณต‚ฌ๋˜–ด„œ  „‹ฌ๋œ‹ค. ฑธ ƒฐ•ด๋ผ.
~cpp 
    class exception { ... };

    void someFunction()
    {
        static exception ex;        // ด๋ ‡ฒŒ ๋ฉ”๋ชจ๋ฆฌ— •ƒ กดžฌ•˜๋Š” ฒด๋งŒ„  „‹• ˆ˜ žˆ๋‹ค.
        ...
        throw &ex;    // ฌ„ฐ๋กœ  „‹ฌ, •ด๋‹•ˆ˜ ˜—ญ„ ๋ฒ—–ด๋‚˜๋ฏ€๋กœ, static๋งŒ‚ด•„ ๋‚จ„ˆ˜ žˆ๋‹ค.
        ...
    }
    void doSomething()
    {
        try{
            someFunction();         // —ฌธฐ—„œ exception *„ ๋˜„‹ค.
        }
        catch ( exception *ex) {    // exception* „ žก  •„๋ฌด๋Ÿฐ ฒด๋„ ๋ณต‚ฌ๋˜ง€ •Š๋Š”๋‹ค.
            ...
        }
    }

ฝ”๋“œ๋Š” นจ๋—•˜ฒŒ ๋ณดง€๋งŒ, œ„ ฑ…€ •„‹ˆ๋‹ค. ด๋Ÿฐ „ œ„•„œ ”„๋กœธ๋ž˜๋จธ๋Š” ˜ˆ™ธ ฒด๋ฅผ •ƒ ’ˆ žˆ๋Š” ”„๋กœธ๋žจ„ ž‘„••• ฒƒด๋‹ค. „‹žˆ  „—ญ(Global) staitcœผ๋กœ „ –ธ•˜๋ฉด ๋œ‹  ๋ฐ˜๋ฌธ•˜ ง€๋งŒ,  „—ญ˜ œ„—˜„€ ”„๋กœธ๋ž˜๋จธฐ€ ฑธ ‰ฝฒŒ นŒ๋จน„ˆ˜ žˆ๋‹ค๋Š”๋ฐ žˆ๋‹ค. ๋‹Œ ˜ˆ œ๋ฅผ ๋ณด๋ฉด
~cpp 
void someFunction()
{
    exception ex;       // local ˜ˆ™ธ ฒดธ๋ฐ •ˆ˜˜ ˜—ญ„ ๋ฒ—–ด๋‚˜๋ฉด ŒŒดด๋˜–ด „‹ค.

    ...
    throw &ex;          // ธ๋Ÿผ ฑด ๋งงฑ —›ด๋ผ๋Š” †Œ๋ฆฌ ด๋ฏธ ŒŒดด๋œ ฒด๋ฅผ ฐ€๋ฆฌ‚ค  žˆœผ๋‹ˆ
    ...
}
ž ฑด ๋‚˜œ ฝ”๋“œ˜ œ ˜•ฒƒด๋‹ค. ฃผ„—„œ –ธธ‰•œฒƒณผ ฐ™•ˆ˜—„œ ๋ฒ—–ด๋‚˜๋ฉด new๋‚˜ static•„‹Œƒ ๋งŒ๋“ค–ด„ ฒด๋Š” ŒŒดด๋˜–ด „‹ค. ธ๋ฆฌ  catch—„œ๋Š” ŒŒดด๋˜–ด„ ฒด˜ ฃผ†Œ ฐ’„ ๋ฐ›ฒŒ ๋˜๋Š” ฒƒด๋‹ค.

•ด๋‹ฝ”๋“œ๋ฅผ ๋‹Œณผ ฐ™ด new heap object๋กœ ๋Œ€ฒด• ˆ˜ žˆ„ ฒƒด๋‹ค.
~cpp 
    void someFunction() 
    {
        ...
        throw new exception;    // ฒƒ๋„ –ดฐ€ žˆ๋Š”ฒŒ, new—„œ ˜ˆ™ธ ๋ฐœƒ•˜๋ฉด –ด๋–ปฒŒ • ฒƒฐ€?
        ...
    }

ฒƒ๋„ ”ผ•••  ๋ฐฉ๋ฒ•ด๋‹ค. ™œ๋ƒ•˜๋ฉด I-just-caught-a-pointer-to-a-destoyed-object ๋ฌธ œ•Œ๋ฌธด๋‹ค. ฒŒ๋‹ฐ€ catchตฌ๋ฌธ—„œ ง๋ฉด•œ˜•˜๋‚˜˜ ๋ฌธ œ๋Š” ๋Œ€ฒด ฌ„ฐ๋ฅผ ๋ˆ„ฐ€ –ด๋””„œ ง€šฐ๋А๋ƒ ด๋‹ค. ๋‹ค๋ฅธ ๋ฉดœผ๋กœ ƒฐ•ด๋ณผ ๋ฌธ œ๋Š” ˜ˆ™ธ ฒดฐ€ heapƒ— ๋ฐฐ˜๋œ‹ค๋ฉด ง€›Œ ง€ง€ •Š€ ˜ˆ™ธ ฒด๋Š” ‹€ž„—†ด resource leak๋ฅผ ๋ฐœƒ ‹œ‚ฌ ฒƒด๋‹ค. ๋„ˆ๋ฌด ๋ป”•œ •ธฐ ฐ€. ธ๋ฆฌ  ”„๋กœธ๋žจ˜ –‰๋ณดฐ€ –ด๋–ปฒŒ ๋ ง€ ˜ˆธก • ˆ˜๋„ —†๋‹ค. •ˆธ๋Ÿฐฐ€?

๋ช‡๋ช‡ ด๋–ธŠธ๋Š”  „—ญ(global)ด๋‚˜  •  ฒด๋ฅผ(static object)˜ ฃผ†Œ๋ฅผ ๋„˜ธฐž  ๋ง•˜ , ๋ช‡๋ช‡€ heapƒ˜ ˜ˆ™ธ ฒด˜ ฃผ†Œ๋ฅผ  „‹•˜ž  ๋ง•œ‹ค. ˜๋Ÿผ ฌ„ฐ๋ฅผ †ต•œ ˜ˆ™ธ˜  „‹€ (Catch by pointer) •„๋ฆฌ†ก•œ ๋ฌธ œ๋ฅผ ๋ฐœƒ ‹œ‚จ๋‹ค. ง€›Œ กŒ๋Š”ฐ€? •ˆง€›Œ กŒ๋Š”ฐ€? •ƒ ๋Œ€๋‹€ ™•‹•˜ง€ •Š๋‹ค.

ฒŒ๋‹ฐ€ catch-by-pointer(ฌ„ฐ๋ฅผ †ต•œ ˜ˆ™ธ  „‹ฌ)€ –ธ–ดƒ—„œ ‚ฌ๋žŒ๋“ค˜ ๋Œ€๋ฆฝ„ œ ๋„ •œ‹ค. ๋„ฐ€ง€˜ ‘œค€ ˜ˆ™ธ ฒด๋“ค๋“ค( bad_alloc(Item 8:operator new—„œ ๋ถˆถฉ๋ถ„•œ ๋ฉ”๋ชจ๋ฆฌ ๋ฐ˜™˜), bad_cast(Item 2:dynamic_cast—„œ ฐธกฐ ‹Œจ), bad_typeid(dynamic_castผ๋•Œ nullฌ„ฐ๋กœ ๋ณ€™˜), bad_exception(Item 14:˜ˆธก ๋ชป•˜๋Š” ˜ˆ™ธ๋กœ ๋น ง€๋Š” ฒƒ unexpected exception ๋ฌธ œ) ฐ€ ˜ˆ™ธ ฒด๋“ค˜ ๋ชจ๋“  ฒƒธ๋ฐ, ด๋“ค„ –ฅ•œ ธฐ๋ณธ ฌ„ฐ๋Š” กดžฌ•˜ง€ •Š๋Š”๋‹ค. ธ๋ž˜„œ‹‹ € ˜ˆ™ธ๋ฅผ ฐ’œผ๋กœ(by value)˜€ ฐธกฐ๋กœ(by reference) ๋ฐ–—๋Š” ๋Œ€•ˆ—†๋‹ค.

Catch-by-value๋Š” ‘œค€ ˜ˆ™ธ ฒด๋“ค ƒ——„œ ˜ˆ™ธ ฒด˜ ‚ญ œ ๋ฌธ œ— ด€•„œ  ๋ฏผ•  •„š”ฐ€ —†๋‹ค. •˜ง€๋งŒ ˜ˆ™ธฐ€  „‹ฌ๋ •Œ ‘๋ฒˆ˜ ๋ณต‚ฌฐ€ ด๋ฃจ–ด „‹ค๋Š”ฒŒ ๋ฌธ œ‹ค. (Item 12ฐธ ) ฒŒ๋‹ฐ€ ฐ’œผ๋กœ˜  „‹€ slicing problemด๋ผ๋Š” ๋ฌธ œ๋ฅผ ๋ฐœƒ‹œ‚จ๋‹ค. ฒŒ ๋ญ๋ƒ •˜๋ฉด, ๋งŒ•‘œค€ ˜ˆ™ธ ฒด—„œ œ ๋„(ƒ†)•„œ ๋งŒ๋“ค–ด„ ˜ˆ™ธ ฒด๋“ค•ด๋‹ฒด˜ ๋ถ€๋ชจ๋กœ ๋˜ € „‹ค๋ฉด, ๋ถ€๋ชจ ŒŒŠธ ๋ถ€๋ถ„๋งŒ ฐ’œผ๋กœ‘๋ฒˆงธ ๋ณต‚ฌ‹œ— ๋ณต‚ฌ๋˜–ด„œ  „‹ฌ๋˜–ด ๋ฒ„๋ฆฐ๋‹ค๋Š” ๋ฌธ œ‹ค. ฆ‰ ž˜ผ๋ฒ„๋ฆฌ๋Š” ๋ฌธ œ "slice off" ๋ผ๋Š” ‘œ˜„ด ๋“ค–ด ฐˆ๋งŒ •˜ ง€. ธ๋“ค˜ data member๋Š” •„๋งˆ ๋ถ€กฑ•ƒฒจ ๋ฒ„๋ฆด ฒƒ  •ด๋‹ฒดƒ—„œ ฐ€ƒ •ˆ˜๋ฅผ ๋ถ€๋ฅผ๋•Œ —ญ‹œ ๋ฌธ œฐ€ ๋ฐœƒ•ด ๋ฒ„๋ฆด ฒƒด๋‹ค. •„๋งˆ ๋ฌดกฐฑด ๋ถ€๋ชจ ฒด˜ ฐ€ƒ •ˆ˜๋ฅผ ๋ถ€๋ฅดฒŒ ๋  ฒƒด๋‹ค.(ฐ™€ ๋ฌธ œ๋Š” •ˆ˜— ฒด๋ฅผ ฐ’œผ๋กœ„˜ธธ๋•Œ๋„˜‘ฐ™ œธฐ ๋œ‹ค.) ˜ˆ๋ฅผ ๋“ค–ด„œ‹Œ„ ƒฐ•ด ๋ณดž
~cpp 
    class exception {
    public:
        virtual const char * what() throw();
        ...
    }

    class runtime_error:public exception{ ... };

    class Validation_error : public runtime_error{      // ž •ด๋‹ฒด๋Š” runtime_error๋ฅผ ƒ†•„œ ๋งŒ๋“ค—ˆ 
    public:             
        virtual const char * what() throw();            // ฐ€ƒ•ˆ˜๋Š” exceptionƒ— žˆ๋Š” ฒƒด๋‹ค.
        ...
    }
    void someFunction()
    {
        ...
        if ( a validation …ŒŠคŠธ ‹Œจ){
            throw Validation_error();
        }
        ...
    }
    void doSomething()
    {
        try{
            someFunction();
        }
        catch (exception ex) {      // item 12—„œ –ธธ‰–ˆ๋“ฏ exception˜ ž‹ ˜ˆ™ธฒด๋“ค€ ๋‹žกžŒ๋‹ค.
            cerr << ex.what();      // ฐ’œผ๋กœ ๋ถ€๋ชจ๋งŒ ๋ณต‚ฌ–ˆธฐ ๋•Œ๋ฌธ— what() ฐ€ƒ•ˆ˜๋Š” exceptionƒ˜ 
                                    // ฐ€ƒ •ˆ˜ฐ€ ๋ถˆ๋ฆฐ๋‹ค. œ๋ฐœž˜ ˜๋„๋Š” Validation_error ƒ˜ ฐ€ƒ•ˆ˜๋ฅผ
                                    // ๋ถ€๋ฅดธธ ›•˜๋Š” ฒƒ —ˆ๋‹ค.
            ...
        }
    }
ฃผ„— –ธธ‰๋˜–ด žˆ๋“ฏด ๋ฒ„ „€ slicing ๋ฌธ œฐ€ ๋ฐœƒ•œ‹ค. ตฌฐจ•œ „ค๋ช… €ฐฎ๋‹ค. ฒฐ๋ก € ฐ’œผ๋กœ(by value)˜ ˜ˆ™ธ ฒด  „‹€ ด๋Ÿฐ slicing ๋ฌธ œ๋กœ‹‹ ›•˜๋Š” –‰๋™„  ˆ๋Œ€๋กœ ๋ชป•œ‹ค.

žž ธ๋Ÿผ ๋‚จ€ฑด ˜ง catch-by-reference(ฐธกฐ๋กœ„œ ˜ˆ™ธ  „‹ฌ)ด๋‹ค. catch-by-reference๋Š”  œนŒง€˜ ๋…ผ˜๋ฅผ นจ๋——†•  ค€๋‹ค. catch-by-pointer˜ ฒด ‚ญ œ ๋ฌธ œ™€ ‘œค€ ˜ˆ™ธ ƒ€ž…๋“ค„ žก๋Š”ฑฐ— ๋Œ€•œ –ด๋ ›€, catch-by-value™€ ฐ™€ slicing ๋ฌธ œ๋‚˜‘๋ฒˆ ๋ณต œ๋˜๋Š” –ด๋ ›€—†๋‹ค. ฐธกฐ๋กœ„œ ˜ˆ™ธ  „‹—„œ ˜ˆ™ธ ฒด๋Š” ˜ง •œ๋ฒˆ ๋ณต‚ฌ๋˜–ด งˆ ๋ฟด๋‹ค.

‹Œ ˜ˆ œ๋ฅผ ๋ณดž.
~cpp 
void someFunction()
{
    ...
    if ( validation …ŒŠคŠธ —๋Ÿฌ ){
        throw Validataion_error();
    }
    ...
}

void doSomething()
{
    try{
        someFunction();
    }
    catch (exception& ex){      // ด๋ถ€๋ถ„„ ฐธกฐ๋กœ๋งŒ ๋ฐ”พธ—ˆ๋‹ค.  „˜ ˜ˆ œ™€ Šน๋ณ„žˆ ๋ฐ”๋€ฒŒ —†๋‹ค.
                                // •˜ง€๋งŒ ด๋ถ€๋ถ„ด ๋ฐ”๋€Œ–ด„œ
        cerr << ex.what();      // —ฌธฐ„œ˜ ฐ€ƒ •ˆ˜๋„ Validation_error˜ ๋ฉ”†Œ๋“œฐ€ ๋ถˆ๋ฆฐ๋‹ค.
        ...
    }
}

•ด๋‹†ŒŠค๋Š” catch—„œ ฐธกฐ๋กœ๋งŒด ๋ฐ”๋€Œ—ˆ๋‹ค. &•˜๋‚˜๋งŒถ”ฐ€๋˜–ด ง€ธˆนŒง€  œธฐ๋œ ๋ฌธ œฐ€ ‚ฌ๋ ธ ๋ฒ„๋ฆฐ๋‹ค.

catch-by-reference๋Š”  œนŒง€˜ ๋ฌธ œ— ๋ชจ๋“  •ฒฐฑ…„  œ‹œ•œ‹ค. (slicing, delete๋ฌธ œ etc)ธ๋Ÿผ  œ ฒฐ๋ก € •˜๋‚˜ •„‹นŒ?

Catch exception by reference!

1.6. Item 14: Use exception specifications judiciously.

  • Item 14: ˜ˆ™ธ๋ฅผ ‹ ‘•˜ฒŒ ‚ฌšฉ•˜ผ.
(judiciously- ‹ ‘•œ)

ผ๋‹ฃผ œ๋ฅผ ๋ถ€ ••˜๋Š” ด๋Š” —†œผ๋ฆฌ๋ผ.:˜ˆ™ธ๋Š”   ˆ•œ ณณ— ‘œ˜„๋˜–ด••œ‹ค. ธ๋“ค€ ฝ”๋“œ๋ฅผ ๋” •ฐ€ธฐ Žธ•˜ฒŒ ๋งŒ๋“ค–ด ค€๋‹ค. ™œ๋ƒ•˜๋ฉด •„๋งˆ ๋ช…‹œ œผ๋กœ ‘œ˜„๋œ ˜ˆ™ธ ƒƒœฐ€  „‹ฌ(๋˜ €:throw-•˜ ๋˜„‹ค๋Š” ‘œ˜„œผ๋กœ) ๋  ฒƒธฐ ๋•Œ๋ฌธด๋‹ค. ธ๋ ‡ง€๋งŒ ˜ˆ™ธ๋Š” ฃผ„(comment)๋ณด๋‹ค๋Š” ๋ชจ˜•˜‹ค. ปดŒŒผ๋Ÿฌ๋Š” ๋•Œ๋•Œ๋กœ ปดŒŒ‘—  •™•žˆ ˜•˜ง€ •Š€ ˜ˆ™ธ๋“ค„ ๋ฐœฒฌ• ˆ˜๋„ žˆœผ๋ฉฐ, ๋งŒ••ˆ˜ฐ€ ˜ˆ™ธ ŠคŽ™(๋ช…„ธ:•˜๋ช…„ธ)ƒ—  œ๋Œ€๋กœ ๋ช…ธฐ๋˜ง€ •Š€ ˜ˆ™ธ๋ฅผ  „‹ฌ(๋˜กŒ)๋‹ค๋ฉด ž˜๋ชป€ ‹–‰‹œ„(runtime)— ๋ฐœฒฌ๋œ‹ค. ธ๋ฆฌ  Šน๋ณ„•œ •ˆ˜ธ unexpected๋Š” ž๋™œผ๋กœ ๋ถˆ๋ฆฌฒŒ ๋œ‹ค. ด๋ ‡๋“  ˜ˆ™ธ˜๋ฆฌ๋Š” ƒ๋‹žˆ ๋งค๋  ธ ๋ฉด„ ฐ€ง€  žˆ๋‹ค.

  • •˜ง€๋งŒ ๋ณด†ต •„๋ฆ„‹›€€ ‘œ๋ฉด•„‹Œ ๋‚ด๋ฉด— กดžฌ•œ‹ค.
unexpected— ด€๋ •œ ธฐ๋ณธ –‰๋™€ terminate๋ฅผ ˜œ•„œ terminate๋‚ด—„œ abort๋ฅผ ˜œ๋กœ • œ๋กœ ”„ธ๋žจ„ ๋ฉˆถ”ฒŒ •œ‹ค. ˜๋ฏธ๋Š” ๋ฐ”๋กœ abort๋Š” ”„๋กœธ๋žจ„ ข…๋ฃŒ• •Œ นจ๋—ง€šฐ๋Š” ณผ •„ ƒ๋žต•˜ธฐ ๋•Œ๋ฌธ— ™œ„™”๋œ Šคƒ ”„ ˆž„๋‚ด˜ ง€—ญ ๋ณ€ˆ˜๋Š” ŒŒดด๋˜ง€ •Š๋Š”๋‹ค.(ฆ‰, ”„๋กœธ๋žจด ๋ฉˆถ”  ๋””๋ฒ„‹œ ƒ™ฉ— ˜„žฌ˜ ž๋ฃŒ ฐ’„ กฐ‚ฌ• ˆ˜ žˆ๋‹ค๋Š” ˜๋ฏธ). ธ๋ž˜„œ ˜ˆ™ธ ˜๋ฆฌ˜ ๋ช…„„ –ดธด ๋ฌธ œ๋Š” ƒ๋‹žˆ ‹ฐ•œ ƒ™ฉด๋‚˜, ฑฐ˜ ๋ฐœƒ•˜ง€ •Š€ ƒ™ฉด๋‹ค. ๋ถˆ–‰žˆ๋„ ธ๋Ÿฐ ‹ฐ•œ ƒ™ฉ„ ด๋ฅดฒŒ •˜๋Š” •ˆ˜ ž‘„šฉ•˜‹ค๋Š”ฒŒ ๋ฌธ œด๋‹ค. ปดŒŒผ๋Ÿฌ๋Š” ˜ง ˜ˆ™ธ ๋ช…„— ž…ฐ•œ๋Œ€๋กœ ๋ถ€๋ถ„ œผ๋กœ ˜ˆ™ธ ‚ฌšฉ— ด€•œ ฒ€‚ฌ๋ฅผ •œ‹ค. ˜ˆ™ธฐ€ žก„ˆ˜ —†๋Š”ฒƒ-–ธ–ด ‘œค€ ƒ—„œ ฑฐ๋ถ€•˜๋Š”(๋น„๋ก ฃผ˜(wanning)ง€๋ผ๋„) ธˆง€•˜๋Š” ฒƒ- € •ˆ˜๋ฅผ ˜œ• •Œ ˜ˆ™ธ ๋ช…„—„œ ๋ฒ—–ด๋‚˜๋Š” •ˆ˜ฒƒด๋‹ค.

‹Œ˜ f1•ˆ˜— ฐ™•„๋ฌด๋Ÿฐ ˜ˆ™ธ๋ฅผ ๋ฐœƒ •ˆ‹œ‚ค๋Š” •ˆ˜— ด€•„œ ƒฐ•ด ๋ณดž.  €๋Ÿฐ •ˆ˜๋Š” •„๋งˆ –ด๋– •œ ˜ˆ™ธ๋ผ๋„ ๋ฐœƒ‹œ‚ฌˆ˜ žˆ„ ฒƒด๋‹ค.
~cpp 
    extern void f1();
ž ธ๋Ÿผ ˜ˆ™ธ ๋ช…„ šฉ๋œ f2๋ฅผ ๋ณดž. ๋‹Œ€ ˜ง int๋งŒ„ ˜ˆ™ธ๋กœ ๋˜งˆฒƒด๋‹ค.
~cpp 
    void f2() throw(int);
f1ด f2˜ •ˆ˜ ๋ช…„ณผ ๋‹ค๋ฅธ ˜ˆ™ธ๋ฅผ ๋˜ง€๋”๋ผ๋„, C++ƒ—„œ๋Š” f2—„œ f1๋ฅผ ๋ถ€๋ฅด๋Š”ฒƒ„ —ˆšฉ•œ‹ค.
~cpp 
    void f2() throw(int)
    {
        ...
        f1();
        ...
    }
ด๋Ÿฐ œ —ฐ•œ ฒฝšฐ๋Š” ๋งŒ•˜ˆ™ธ ๋ช…„— ด€•œ ƒˆ๋กœšด ฝ”๋“œฐ€ ณผฑฐ˜ ˜ˆ™ธ ๋ช…„ฐ€ ๋ถ€กฑ•œ ฝ”๋“œ™€ ž˜ ฒฐ•• ˆ˜ žˆŒ„ ๋ณดธ๋‹ค.

‹‹ ˜ ปดŒŒผ๋Ÿฌฐ€ ˜ˆ™ธ ˜๋ฆฌœ •— ๋งŒกฑ•˜ง€ •Š€ ๋ฃจ‹„ ฐ€„ •ˆ˜˜ ฝ”๋“œ๋ฅผ ˜œ•˜๋Š”๋ฐ ๋ณ„ ๋ฌด๋ฆฌ—†๋‹ , ธ๋Ÿฌ•œ ˜œ•„๋งˆ ๋‹‹ ˜ ”„๋กœธ๋žจ—„œ ”„๋กœธ๋žจ˜ ‘ง€๋ฅผ œ ๋„•˜ธฐ ๋•Œ๋ฌธ— ๋‹‹ € †Œ”„Šธ›จ–ด๋ฅผ ๋งŒ๋“ค๋•Œ œ๋Œ€•œ ธ๋Ÿฐ ๋งŒกฑ๋˜ง€ •Š€ ˜œ„ œ†Œ™” •˜๋„๋ก ฒฐณผ๋ฅผ œ ๋„••• ฒƒด๋‹ค. ‹œž‘‹œ ฐ€žฅ ‹€ ๋ฐฉ–ฅ€ …œ”Œ๋ฆฟƒ—„œ˜ ˜ˆ™ธ ŠคŽ™๋ฅผ œ๋Œ€•œ ”ผ•˜๋Š” ฒƒด๋‹ค. ž ๋‹Œ˜ –ด๋– •œ ˜ˆ™ธ๋„ ๋˜ง€ง€ •Š€ …œ”Œ๋ฆฟ„ ƒฐ•ด ๋ณดž.
~cpp 
    template<class T>
    bool operator==(const T& lhs, const T& rhs) throw()
    {
        return &lhs == &rhs;
    }
…œ”Œ๋ฆฟ€ oprator== •ˆ˜๋ฅผ ๋ชจ๋“  ˜•—  šฉ‹œ‚ค๋Š” ฒƒด๋‹ค. •„๋งˆ ฐ™€ ฃผ†Œ— ฐ™€ ƒ€ž…ด๋ฉด true๋ฅผ ๋ฐ˜™˜•˜ง€๋งŒ •„‹ˆ๋ผ๋ฉด ฒƒ€ false๋ฅผ ๋ฐ˜™˜•œ‹ค. ด๋Ÿฐ …œ”Œ๋ฆฟ€ •„๋ฌด๋Ÿฐ ˜ˆ™ธ๋„ ๋˜ง€ง€ •Š€ …œ”Œ๋ฆฟœผ๋กœ ๋ถ€„•ˆ˜ฐ€ ๋งŒ๋“ค–ดง€๋Š” ƒƒœ— ๋”ฐ๋ ••œ ˜ˆ™ธฐ€ ฌ•จ๋œ‹ค. •˜ง€๋งŒ ฒƒ€ ผญ ‚ฌ‹•„‹ˆ๋‹ค. ™œ๋ƒ•˜๋ฉด operator&(ฃผ†Œ ๋ฐ˜™˜ operator)ฐ€ฐ€ ผญ ฐ™€ ๋ช‡๋ช‡˜ ˜•๋“ค„ œ„•„œ overload๋˜—ˆธฐ ๋•Œ๋ฌธด๋‹ค. ๋งŒ•‚ฌ‹ธ๋Ÿฌ•˜‹ค๋ฉด operaotr&ฐ€ operator== •ˆชฝ—„œ ๋ถˆ๋ฆด๋•Œ ˜ˆ™ธ๋ฅผ ๋˜งˆ ฒƒด๋‹ค. ธ๋ ‡ฒŒ ๋˜๋ฉด šฐ๋ฆฌ˜ ˜ˆ™ธ ๋ช…„ธ๋Š” ฑฐ๋ถ€๋˜ , ณงžฅ unexpected ๋กœ ง„•˜ฒŒ ๋˜๋Š”ฑฐ๋‹ค.

ด๋Ÿฌ•œ Šน๋ณ„๋‚œ ˜ˆ œ๋Š” ๋” ผ๋ฐ˜ ธ ๋ฌธ œ๋กœ, ๋‹‹œ ๋ง•˜ž๋ฉด …œ”Œ๋ฆฟ˜ ˜• ž๋กœ  „‹ฌ๋˜๋Š” ˜ˆ™ธ— ด€•œ  •๋ณด๋ฅผ •Œ•„๋‚ผ ธธ—†๋‹ค๋Š”  ๋„ •œ๋ชซด๋‹ค. šฐ๋ฆฌ๋Š” ฑฐ˜ …œ”Œ๋ฆฟ„ œ„•œ ˜๋ฏธžˆ๋Š” ˜ˆ™ธ ๋ช…„ธ๋ฅผ  œณต• ˆ˜ —†๋‹ค๋Š” •ธฐ๋‹ค. ™œ๋ƒ•˜๋ฉด …œ”Œ๋ฆฟ€ ฑฐ˜ ๋ณ€•—†ธ๋“ค˜• ž๋ฅผ ๋ช‡ฐ€ง€˜ ๋ฐฉ‹œผ๋กœ๋งŒ “ฐธฐ ๋•Œ๋ฌธด๋‹ค. ฒฐ๋ก €? …œ”Œ๋ฆฟณผ ˜ˆ™ธ๋Š” –ดšธ๋ฆฌง€ •Š๋Š”๋‹ค.!

  • ‘๋ฒˆงธ๋กœ‹‹ € unexpected˜œ„ ๋ง‰ธฐœ„•˜—ฌ ๋ถ€กฑ•œ ˜ˆ™ธ ๋ช…„˜ œ •œผ๋กœ •˜—ฌ ๋ถˆ๋ฆฌ๋Š” •ˆ˜ƒ—„œ ˜ˆ™ธ ๋ช…„ธ๋ฅผ ƒ๋žต• ˆ˜ žˆ๋‹ค.
ฒƒ€ „‹•˜  ผ๋ฐ˜ ƒฐง€๋งŒ, žƒ–ด๋ฒ„๋ฆฌธฐ ‰ฌšด ฒฝšฐด๋‹ค. ๋‹Œ˜ callback •ˆ˜ ๋“ฑ๋ก— ด€•œ ˜ˆ œ๋ฅผ ๋ณดž
~cpp 
typedef void (*CallBackPtr) (int eventXLocation, int event YLocation, void *dataToPassBack);

class CallBack{
public:
    CallBack(CallBackPtr fPtr, void *dataToPassBack) :func(fPtr), data(dataToPassBack){}

    void makeCallBack(int eventXLocation, int eventYLocation) const throw();
private:
    CallBackPtr func;
    void *data
}

    void CallBack::makeCallBack(int eventXLocation, int eventYLocation)
    {
        func(eventXLocation, eventYLocation);
    }
ฝ”๋“œ—„œ makeCallBack—„œ func„ ˜œ•˜๋Š”ฒƒ€ funcด ๋˜ง€๋Š” ˜ˆ™ธ— ฒƒ„ •Œธธ—†–ด„œ ˜ˆ™ธ ๋ช…„— œ„๋ฐ˜•˜๋Š” œ„—˜•œ ƒ™ฉœผ๋กœ ฐˆˆ˜ žˆ๋‹ค.

ด๋Ÿฐ ๋ฌธ œ๋Š” ๋‹Œณผ ฐ™CallBackPtrƒ˜ ˜ˆ™ธ ๋ช…„ธ๋ฅผ ข€๋” ตฌฒด™” ‹œœ„œ  œฑฐ• ˆ˜ žˆ๋‹ค.
~cpp 
typedef void (*CallBackPtr) (int eventXLocation, int event YLocation, void *dataToPassBack) throw();
‹Œณผ ฐ™˜•„ –ธ๋˜—ˆœผ๋ฉด callback•ˆ˜ ๋“ฑ๋ก‹œ •„๋ฌดฒƒ๋„ ๋˜ง€ง€ •Š๋Š”๋‹ค๋Š” กฐฑดด๋ผ๋ฉด ˜ˆ™ธ๋ฅผ ๋ฐœƒ• ฒƒด๋‹ค.
~cpp 
    // ˜ˆ™ธ ๋ช…„ฐ€ —†๋Š” •ˆ˜
    void callBackFcn1(int eventXLocation, int event YLocation, void *dataToPassBack);
    void *vallBackData;
    ...
    CallBack c1(callBackFcn1, callBackData); // —๋Ÿฌ๋‹ค callBackFcn1€ —ฌธฐ—„œ ˜•ด ๋งžง€ •Š•„. —๋Ÿฌ๋ฅผ ๋˜งˆฒƒด๋‹ค.

    // ˜ˆ™ธ ๋ช…„ฐ€ žˆ๋Š” •ˆ˜
    void callBackFcn2(int eventXLocation, int event YLocation, void *dataToPassBack); throw()
    CallBack c1(callBackFcn2, callBackData); // ๋ณด๋‹‹œ”ผ •Œ๋งž๋Š” ˜•ด๋‹ค.

ด๋Ÿฌ•œ •ˆ˜ ฌ„ „‹‹œ ด€๋ € œ— ถ”ฐ€๋œฑฐ๋‹ˆ ๋งŒ•ปดŒŒผ๋Ÿฌฐ€ ง€› ๋ชป•œ‹  •ด๋„ ๋†€๋ž„ฒƒ€ —†๋‹ค. (ฑ…€ 1996๋…„— ๋‚˜™”๋‹ค. •˜ง€๋งŒ ง€ธˆ๋„(2001๋…„ •๋„)  œ๋Œ€๋กœ ง€›•˜๋Š” ปดŒŒผ๋Ÿฌฐ€ ๋งŽง€ •Š€ฑธ๋กœ •ˆ๋‹ค.) ๋งŒ•ปดŒŒผ๋Ÿฌฐ€ ˜๋ฆฌ ๋ชป•œ‹ค๋ฉด ด๋Ÿฐ ‹ˆ˜˜ ๋ฐฉง€๋Š” ๋‹‹  ž‹ —ฒŒ ๋‹ฌ๋ ธ๋‹ค.

  • „ธ๋ฒˆงธ๋กœ‹‹ € "the system"•„๋งˆ ๋˜ง€๋Š” ˜ˆ™ธ๋ฅผ •ธ๋“ค๋ง•„œ unexcepted˜ ˜œ„ ”ผ• ˆ˜ žˆ๋‹ค. ด๋Ÿฌ•œ ˜ˆ™ธ๋Š” ๋งŽ€ ๋ถ€๋ถ„ด new™€ new[]‹œ ๋ฉ”๋ชจ๋ฆฌ • ‹˜ˆ™ธ—„œ bad_allocด ๋ฐœƒ•˜—ฌ ๋ฐœƒ•œ‹ค. ๋งŒ•ฝ ๋‹‹ ด new๋ฅผ –ด๋–ค •ˆ˜—„œ “ด๋‹ค๋ฉด šฐ—ฐด๋ผ๋„ bad_alloc ˜ˆ™ธ๋ฅผ ๋งŒ๋‚ ˆ˜ žˆ๋Š” ฐ€๋Šฅ„„ ๋‚ดฌ•˜๋Š” …ˆด๋‹ค.

ž, ง€ธˆ 1˜Šค˜ ˜ˆ๋ฐฉ๋Š” ฐจ›„ 1ŒŒšด๋“œ˜ ”ผ•ด๋ณด๋‹ค ๋‚ณง€๋งŒ ๋•Œ๋กœ๋Š” ˜ˆ๋ฐฉ–ด๋   ”ผ•ฐ€ ๋” ‰ฌšด ฒฝšฐ๋„ žˆœผ๋ฆฌ๋ผ. –ธธ‰•œ ฒƒ˜๋Ÿผ ๋•Œ๋•Œ๋กœ unexpected ˜ˆ™ธ ง ‘ ๋งž„œ๋Š” ฒƒ€ ˜Œ— ฒƒ„ —๋ฐฉ•˜๋Š”ฒƒ ๋ณด๋‹‰ฝ๋‹ค. ˜ˆ๋ฅผ๋“คž๋ฉด ๋งŒ•ฝ ๋‹‹ ˜ˆ™ธ๋ช…„ธ๋ฅผ —„ฒฉ•˜ฒŒ ž‘„–ˆง€๋งŒ ๋‹‹ € ˜ˆ™ธ ๋ช…„ฐ€ ๋˜–ด žˆง€ •Š€ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ˜ •ˆ˜๋“ค„ • œ๋กœ ๋ถ€๋ฅผˆ˜ žˆ๋‹ค. •ˆ˜ƒ—„œ ฝ”๋“œ๋“คด ๋ฐ”๋€Œ๋Š”  •ด๋„œ unexpected˜ˆ™ธ๋ฅผ ๋ง‰๋Š”ฒƒ€ ๋น„‹šฉ ด๋‹ค.

๋งŒ•ฝ unexpected˜ˆ™ธ๋ฅผ ๋ง‰๋Š”ฒƒ‹šฉ ง€ ๋ชป•˜‹ค๋ฉด ๋‹‹ € C++ฐ€ unexpected๋ฅผ ๋‹ค๋ฅธ ˜•‹œผ๋กœ ๋ฐ”พธ–ด ๋ฒ„๋ฆฌ๋Š” ธฐ๋Šฅ„ šฉ•„œ ธ๋Ÿฌ•œ ๋น„‹šฉ ƒƒœ๋ฅผ ๋งŒšŒ• ˆ˜ žˆ๋‹ค. ๋‹Œ ˜ˆ๋Š” unexpect™€ ฐ™€ ˜ˆ™ธ๋ฅผ UnexpectedException ฒด๋กœ ๋ฐ”พผฒƒ„ ƒฐ•ด ๋ณธ๋‹ค.
~cpp 
class UnexpectedException {};

void convertUnexpected()
{
    throw UnexpectedException();
}

ธ๋ฆฌ  unexpected •ˆ˜๋ฅผ convertUnexpected๋กœ ตฒด•œ‹ค.
~cpp 
    set_unexpected(convertUnexpected);
ด๋ ‡ฒŒ •˜๋ฉด unexpected˜ˆ™ธ๋Š” convertUnexpected๋ฅผ ˜œ•œ‹ค. ฆ‰, ƒˆ๋กœšด UnexpectedException ฒด๋กœ ˜ˆ™ธฐ€ ตฒด๋˜—ˆ๋‹ค. •˜ง€๋งŒ  œณต๋˜๋Š” ˜ˆ™ธ ๋ช…„—„œ unexpected๋ฅผ ๋ฐฉง€•  ค๋ฉด UnexpectedException ˜ˆ™ธ๋ฅผ ฌ••••œ‹ค. ˜ˆ™ธ๋ฅผ ฒด๋กœ ๋˜กŒธฐ—.. (๋งŒ•˜ˆ™ธ ๋ช…„— UnexpectedException„„ง€ •Š•˜‹ค๋ฉด unexpectedฐ€ ตฒด๋˜ง€ •Š€ ฒƒ˜๋Ÿผ terminateฐ€ ๋ถˆ๋ฆดฒƒด๋‹ค.)

˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•€ unexpected ˜ˆ™ธ๋ฅผ ธ๋ƒฅ unexpected˜ —ญ• „ ˜„žฌ˜ ˜ˆ™ธ๋ฅผ „† ๋˜ง€ธฐ(rethrow)˜•ƒœ๋กœ ๋ฐ”พธ–ด ๋ฒ„๋ฆฌ๋Š” ฒƒด๋‹ค. ด๋ ‡ฒŒ ตฒด•˜๋ฉด ˜ˆ™ธ๋Š” •„๋งˆ ƒˆ๋กœšด ‘œค€˜ bad_exception „ ๋˜ง€๋Š” ˜•ƒœ๋กœ ๋ฐ”๋€๋‹ค. ( •œ C++๋ด๋ธŒ๋Ÿฌ๋ฆฌ— ฌ•จ)
~cpp 
    void convertUnexpected()
    {
        throw()     // ฑด ˜„ œ˜ ˜ˆ™ธ๋ฅผ „† ๋˜„‹ค๋Š” ˜๋ฏธ
    }

    set_unexpected(convertUnexpected);
๋งŒ•œ„™€ ฐ™•˜  bad_exception(‘œค€ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ ƒ˜ exception˜ ธฐ๋ณธ ˜ˆ™ธ ด๋ž˜Šค)๋ฅผ ๋‹‹ ˜ ๋ชจ๋“  ˜ˆ™ธ ๋ช…„— ฌ•‹œ‚ค๋ฉด ๋‹‹ € ฒฐฝ” ๋‹‹ „˜ ”„๋กœธ๋žจด ๋ถˆ‹œ— ๋ฉˆถ”–ด ๋ฒ„๋ฆฌ๋Š”ฒƒ— ๋Œ€•œ ฑฑ •„ •  š”๋Š” —†„ ฒƒด๋‹ค. ฑฐธฐ๋‹ฐ€ œ •— ๋งžง€•Š๋Š” ˜ˆ™ธ๋“ค๋„ bad_exceptionœผ๋กœ ตฒด๋˜  ˜ˆ™ธ๋Š” ธฐ๋ณธ ˜ˆ™ธ ๋Œ€‹ — ๋‹‹œ ๋˜ € ผ„‹ค.(propagate)

--
 œ‹‹ € ˜ˆ™ธ ๋ช…„ฐ€ ๋งŽ€ ๋ฌธ œ๋ฅผ ฐ€ง€  žˆ„ˆ˜ žˆŒ„ •• ฒƒด๋‹ค. ปดŒŒผ๋Ÿฌ๋Š” ธ๋“ค˜ ๋ถ€๋ถ„ “ฐž„ƒˆ๋ฅผ ฒ€‚ฌ•„œ …œ”Œ๋ฆฟ—„œ ๋ฌธ œ๋ฅผ ๋ฐœƒ•  †Œง€๋ฅผ •Šœผ๋ฉฐ, ปดŒŒผ๋Ÿฌ๋Š” ˜™ธ๋กœ œน™œ„๋ฐ˜„ •˜ธฐ ‰ฝ , ปดŒŒผ๋Ÿฌฐ€  œ๋Œ€๋กœ ๋˜ง€ •Šœผ๋ฉด ”„๋กœธ๋žจ„ ๋ถˆ‹œ— ๋ฉˆถ”–ด ง€๋„๋ก œ ๋„• ฒƒด๋‹ค. ˜ˆ™ธ ๋ช…„—ญ‹œ˜๋‹ค๋ฅธ ๋ฌธ œ๋ฅผ •ˆ  žˆ๋Š”๋ฐ, ˜ˆ™ธ๋ช…„ธ๋Š” ๋†’€ ˆ˜ค€˜ ˜œžฐ€ ˜ˆ™ธ ๋ฐœƒ„ ๋Œ€๋น„• •Œ๋„ unexpected๋กœ˜ ฒฐณผ๋ฌผ„ ๋งŒ๋“ค–ด ๋‚ธ๋‹ค.

•ธฐ๋ฅผ œ„•ด Item 11˜ ˜ˆ œ๋ฅผ ธ๋Œ€๋กœ ๋ณดž
~cpp 
    class Session{
    public:
        ~Session();
        ...
    private:
        static void logDestuction(Session *objAddr) throw();
    };

    Session::~Session()
    {
        try{
            logDestruction(this);
        }
        catch ( ... ) {}
    }
Session˜ ŒŒดดž๋Š” logDestruction„ ˜œ•œ‹ค. •˜ง€๋งŒ ๋ช…‹œž‘€ –ด๋– •œ ˜ˆ™ธ๋„ •ด๋‹น logDestruction—„œ ๋˜ง€ง€ ๋ชป•˜๋„๋ก ๋ง‰•„๋†“•˜‹ค. •œ๋ฒˆ logDestuction‹Œจ• •Œ ๋ถˆ๋ฆฌ๋Š” •ˆ˜๋“ค— ๋Œ€•˜—ฌ ƒฐ•ด ๋ณดž. ฒƒ€ •„๋งˆ –ด๋‚˜ง€ •Š„ ฒƒด๋‹ค. šฐ๋ฆฌฐ€ ƒฐ•œ๋Œ€๋กœฑด ƒ๋‹žˆ ˜ˆ™ธ ๋ช…„˜ œ • œ„๋ฐ˜œผ๋กœ ธ๋„•˜๋Š” ฝ”๋“œด๋‹ค. ด๋Ÿฐ ˜ˆธก• ˆ˜ —†๋Š” ˜ˆ™ธฐ€ logDestructionœผ๋กœ ๋ถ€„ผงˆ๋•Œ unexpectedฐ€ ’€๋ฆด ฒƒด๋‹ค. ธฐ๋ณธ œผ๋กœ ฒƒ€ ”„๋กœธ๋žจ„ ๋ฉˆ˜‹ค. ˜ˆ œ๋Š” ฒƒ˜ ˆ˜ • ๋ฒ„ „ง€๋งŒ, ธ๋Ÿฐ ˆ˜–‰„ Session ŒŒดดž˜  œž‘žฐ€ ›• นŒ? ž‘„ž๋Š” ๋ชจ๋“  ฐ€๋Šฅ•œ ˜ˆ™ธ ๋ฅผ žกœผ๋   ๋…ธ๋ •œ‹ค. ธ๋ž˜„œ ฑด Session ŒŒดดž˜ catch๋ธ”๋Ÿญ—„œˆ˜–‰๋˜๋Š” ฒƒด ๋‹ค๋‹ค๋ฉด ฑด ๋ถˆณต‰•œ ˜‚ฌ๋  ๋ณดธ๋‹ค. ๋งŒ•ฝ logDestruction•„๋ฌด๋Ÿฐ ˜ˆ™ธ ๋ช…„ธ๋ฅผ •˜ง€ •Š๋Š”๋‹ค๋ฉด, I'm-willing-to-catch-it-if-you'll-just-give-me-a-chance ‹œ๋‚˜๋ฆฌ˜ค๋Š” ฒฐฝ” –ด๋‚˜ง€ •Š„ฒƒด๋‹ค. (ด๋Ÿฐ ๋ฌธ œ˜ ˜ˆ๋ฐฉœผ๋กœ unexpected˜ ตฒด— ๋Œ€•œ „ค๋ช…„ œ„•–ธธ‰•ด ๋‘—ˆ๋‹ค.)

˜ˆ™ธ ๋ช…„˜  ˜•žˆ๋Š” ‹œฐ€ ‘š”•œฒƒด๋‹ค. ฒƒ€ ˜ˆ™ธ ๋ฐœƒ„ ˜ˆƒ•˜๋Š” •ˆ˜๋“ค˜ ˜ˆ™ธ ข…๋ฅ˜๋“ค„ ๋ณด๋ฉด ›Œ๋ฅญ•œ ๋ฌธ„œ™”ฐ€ ๋ ฒƒ , ž˜๋ชป๋œ ˜ˆ™ธ ๋ช…„˜ ƒ™ฉ•˜˜ ”„๋กœธ๋žจ€ ธฐ๋ณธ œผ๋กœ ฃผ–ดง€๋Š” ƒƒœ ฆ‰, ฆ‰‹œ ๋ฉˆถ”๋Š” ฒƒ„  •‹™”•  ๋งŒผ ž˜๋ชป๋œ ด๋‹ค. ฐ™€ ‹œฐœผ๋กœ ˜ˆ™ธ๋Š” ปดŒŒผ๋Ÿฌ— ˜•˜—ฌ ˜ง ๋ถ€๋ถ„  ฒ€๋งŒ„‹•˜  ˜ˆ™ธ๋Š” ˜๋„•˜ง€ •Š€ ž˜๋ชป„ –‘‚ฐ•˜ธฐ ‰ฌšธฒƒด๋‹ค. ฒŒ๋‹ฐ€ ˜ˆ™ธ๋Š” unexpected ˜ˆ™ธ—„œ ๋ฐœƒ•˜๋Š” ๋†’€ ๋ ˆ๋ฒจ˜ ˜ˆ™ธ žก๋Š” ๋ฌธ œ— ๋Œ€•˜—ฌ ˜ˆ๋ฐฉ• ˆ˜ žˆ๋‹ค.

ž ด๋Ÿฐฒƒ๋“ค˜ˆ™ธ ๋ช…„ธ๋ฅผ ˜„๋ช…•˜ฒŒ ‚ฌšฉ•˜๋Š”๋ฐ กฐ•  ฒƒด๋‹ค. ๋‹‹ ˜ •ˆ˜— ˜ˆ™ธ๋ฅผ ๋”•˜ธฐ  „— ด๋Ÿฐ ‚ฌ•— ๋Œ€•˜—ฌ •œ๋ฒˆฏค ƒฐ•ด ๋ณดž.

1.7. Item 15: Understand the costs of exception handling

  • Item 15: ˜ˆ™ธ •ธ๋“ค๋ง— ๋Œ€•œ ๋น„šฉ ง€๋ถˆ ๋Œ€•œ •

‹–‰‹œ„— ˜ˆ™ธ •ธ๋“ค๋ง„ œ„•˜—ฌ ”„๋กœธ๋ž˜๋จธ๋Š” •œŒ˜ ฝ”๋“œ๋ฅผ ž…๋ •••œ‹ค. ˜ˆ™ธ ‘— ฐž˜ ฌŠธ— ”„๋กœธ๋ž˜๋จธ๋Š” ฐ try๋ธ”๋Ÿญ— ๋“ค–ดฐ€๋Š” ๋ถ€๋ถ„ณผ ๋‚˜˜ค๋Š” ๋ถ€๋ถ„๋”ฐœ„˜ ˜ˆ™ธฐ€ ๋˜ €งˆ๋•Œ ฒด ŒŒดด˜ •„š”„„ ™•••ผ๋งŒ •œ‹ค. ธ๋ฆฌ  ฐ try ๋ธ”๋ก—„œ ”„๋กœธ๋ž˜๋จธ๋Š” catchตฌ๋ฌธ˜ —ฐ„™€ ธ๋“คณผ ด€„๋˜–ด žˆ๋Š” ˜ˆ™ธ ฒด˜ ข…๋ฅ˜— ๋Œ€•˜—ฌ๋„ ƒฐ•ฃผ–ด••œ‹ค. ด๋Ÿฐ ฒƒ๋“ค€ ฒฐฝ” ณตœฐ€ •„‹ˆ๋‹ค. ‹–‰‹œ„๋™•ˆ— ˜ˆ™ธ ๋ช…„— ๋Œ€•œ ™•ž‘—…๋„ ธ๋Ÿฌ๋ฉฐ, catchตฌ๋ฌธ— ฒดฐ€ ๋˜ ง”„•Œ ฒด˜ ŒŒดด ๋ถ€๋ถ„— ๋Œ€•œ ผ๋„ —ญ‹œ ™•žฅ๋œ‹ค. •˜ง€๋งŒ, ๋งŒ•ฝ ๋‹‹ ด try, throw, catch‚ค›Œ๋“œ๋ฅผ ‚ฌšฉ•˜ง€ •Š๋Š”๋‹ค๋ฉด ˜ˆ™ธ •ธ๋“ค๋ง—•ด๋‹จ ๋น„šฉ€ ๋ฐœƒ•˜ง€ •Š , •ด๋‹‚ค›Œ๋“œ๋“ค— ๋Œ€•œ ๋น„šฉ ง€๋ถˆ๋„ ๋ฏธ๋ฏธ•œ –‘ด๋‹ค.

ž ธ๋Ÿผ  „˜€ ˜ˆ™ธ •ธ๋“ค๋ง„ •˜ง€ •Š•˜„•Œ˜ ง€๋ถˆ ๋น„šฉ„ ƒฐ•ด ๋ณดž,‹‹ € ฒด๋“ค žฌ๋˜ , œ ง€๋˜๋Š” Šธ๋ž™•„š”•œ ๋ฐ„ตฌกฐ˜ ‚ฌšฉ„ œ„•ณต„— ๋Œ€•œ ๋น„šฉ ง€๋ถˆ„ •œ‹ค. ธ๋ฆฌ ‹‹ € ด๋Ÿฐ ๋ฐ„ตฌกฐ๋“ค„ ฐฑ‹ •˜  œ ง€•˜๋Š”๋ฐ •„š”•œ ‹œ„— ๋Œ€•œ ๋น„šฉ„ ง€๋ถˆ•œ‹ค. ด๋Ÿฐ ๋น„šฉ๋“ค€ ผ๋ฐ˜ œผ๋กœ  •‹•œ š”ตฌด๋‹ค. ๋ฐ˜๋ฉด— ”„๋กœธ๋žจ˜ˆ™ธ๋ฅผ œ„•œ ง€›—†ปดŒŒผ ๋œ‹ค๋ฉด ˜ˆ™ธ ง€›„ •˜  ปดŒŒ•˜๋Š” ๋ฐ˜๋Œ€˜ ฒฝšฐ๋ณด๋‹ข€๋” ๋น ๋ฅด , ข€๋” ž‘€ šฉ๋Ÿ‰„ ฐจง€•œ‹ค.

ด๋ก  œผ๋กœ‹‹ € ด๋Ÿฐ(˜ˆ™ธ) ๋น„šฉ˜ ง€œ(„ ƒ,select)—†–ด••œ‹ค.:C++˜ •œ ๋ถ€๋ถ„˜ˆ™ธ, ปดŒŒผ๋Ÿฌ๋Š” ˜ˆ™ธ๋ฅผ ง€›•••œ‹ค.

”„๋กœธ๋žจ€ ผ๋ฐ˜ œผ๋กœ ๋…๋ฆฝ œผ๋กœ object ŒŒผ๋“คƒ„ฑ๋˜–ด ง€ , ๋‹ง€ •˜๋‚˜˜ ž‘„ฑ๋˜–ด ๋งŒ๋“ค–ด„ objectŒŒ—„œ ˜ˆ™ธ ˜๋ฆฌฐ€ —†๋‹ค๋ฉด ๋‹ค๋ฅธ ฒƒ๋“คƒ˜ ˜ˆ™ธ ˜๋ฆฌฐ€ •„๋ฌด๋Ÿฐ ˜๋ฏธฐ€ —†ธฐ๋•Œ๋ฌธ—, ๋‹‹ ˜ˆ™ธ˜๋ฆฌฝ”๋“œ๋ฅผ ‚ฌšฉ•˜ง€ •Š๋Š”๋‹ค๋ฉด, ๋‹‹ € ปดŒŒผ๋Ÿฌ  œž‘‚ฌ๋“คด๋Ÿฐ ˜ˆ™ธ๋“ค„ ง€›‹œ –ด๋‚˜๋Š” ๋น„šฉ„ —†•ฒƒด๋  ˜ˆƒ•œ‹ค. ฒŒ๋‹ฐ€ objectŒŒ˜ˆ™ธ๋ฅผ ๋นผธฐœ„••„๋ฌด๋Ÿฐ ƒ˜„˜ ๋งฌฐ€ ๋˜ง€ •Š๋Š”๋‹ค๋ฉด ˜ˆ™ธ ˜๋ฆฌฐ€ ๋“ค–ด„ด๋ธŒ๋Ÿฌ๋ฆฌ™€˜ ๋งฌ๋Š” –ด๋–จนŒ? ฆ‰, ”„๋กœธ๋žจ˜ –ด๋–ค ๋ถ€๋ถ„ด๋ผ๋„ ˜ˆ™ธ๋ฅผ ‚ฌšฉ•œ‹ค๋ฉด ๋‚˜๋จธง€ ”„๋กœธ๋žจ˜ ๋ถ€๋ถ„๋“ค๋„ ˜ˆ™ธ๋ฅผ ง€›•••œ‹ค. ด๋Ÿฐ ๋ถ€๋ถ„  ˜ˆ™ธ ˜๋ฆฌ ƒ™ฉ€ ‹–‰‹œ„—  •™••œ ˜ˆ™ธ๋ฅผ žก๋Š” ˆ˜–‰ด ๋ถˆฐ€๋Šฅ •˜ฒŒ ๋งŒ๋“คฒƒด๋‹ค.

๋ฌผ๋ก   €ฒƒ€ ด๋ก ด๋‹ค. ‹งˆ œผ๋กœ ˜ˆ™ธ ง€› ๋ฐด๋”๋“ค€ ๋‹‹ ˜ˆ™ธ ž‘„„ œ„•œ ฝ”๋“œ˜ ฒจฐ€๋ฅผ ๋‹‹ ˜ˆ™ธ๋ฅผ ง€›•˜๋А๋ƒ ๋งˆ๋А๋ƒ— ๋”ฐ๋กฐ •• ˆ˜ žˆ๋„๋ก ๋งŒ๋“ค–ด ๋†“•˜‹ค.(ž‘„žฃผ:ฆ‰ ˜ˆ™ธ ด€๋ ˜๋ฆฌ˜ on, offฐ€ ฐ€๋Šฅ•˜‹ค.) ๋งŒ•ฝ ๋‹‹ ด ๋‹‹ ˜ ”„๋กœธ๋žจ˜ –ด๋– •œ ˜—ญณผ, —ฐ„๋˜๋Š” ๋ชจ๋“ ด๋ธŒ๋Ÿฌ๋ฆฌ—„œ try, throw, catch๋ฅผ ๋นผ  ˜ˆ™ธ ง€› ‚ฌ•„ ๋นผ ‹‹  ŠคŠค๋กœ †๋„, ฌธฐ ฐ™€ ˜ˆ™ธ˜๋ฆฌ‹œ ๋ฐœƒ•˜๋Š” ๋‹ „  œฑฐ• ˆ˜ žˆ„ ฒƒด๋‹ค. ‹œฐง€๋‚˜ ฐ— ๋”ฐ๋ผ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ— ฐจšฉ๋˜๋Š” ˜ˆ™ธ˜ ˜๋ฆฌ๋Š”    ๋Š˜–ด๋‚˜ฒŒ ๋˜ , ˜ˆ™ธ๋ฅผ  œฑฐ•˜๋Š” ”„๋กœธ๋ž˜๋ฐ€ ฐˆˆ˜๋ก ๋‚ดตฌ„••งˆฒƒด๋‹ค. •˜ง€๋งŒ, ˜ˆ™ธ˜๋ฆฌ๋ฅผ ๋ฐฐ œ•œ ปดŒŒ„ ง€›•˜๋Š” ˜„žฌ˜ C++ †Œ”„Šธ›จ–ด œ๋ฐœƒ˜ ƒƒœ๋Š” ™•‹žˆ ˜ˆ™ธ˜๋ฆฌ ๋ณด๋‹„ฑ๋Šฅ—„œ šฐœ„๋ฅผ  •œ‹ค. ธ๋ฆฌ  ฒƒ€ ๋˜•œ ˜ˆ™ธ  „‹ฌ(propagate) ˜๋ฆฌ™€, ˜ˆ™ธ๋ฅผ ƒฐ•˜ง€ •Š€ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค˜ ‚ฌšฉ— ๋ฌด๋ฆฌ—†๋Š” „ ƒด ๋ ฒƒด๋‹ค.

‘๋ฒˆงธ๋กœ try ๋ธ”๋กœผ๋กœ๋ถ€„˜ ˜ˆ™ธ๋ฅผ žก๋Š”(exception-handling)— ๋Œ€•œ ๋น„šฉ„ ƒฐ•ด ๋ณดž ฒƒ€ ๋‹‹ ด catch๋กœ ˜ˆ™ธ •˜๋‚˜๋ฅผ žกธฐ๋ฅผ ›• •Œ ๋งˆ๋‹š”ตฌ๋˜๋Š” ๋น„šฉด๋‹ค. ฐธฐ ๋‹ค๋ฅธ ปดŒŒผ๋Ÿฌ๋“ค€ „œ๋กœ‹ค๋ฅธ ๋ฐฉ‹œผ๋กœ try๋ธ”๋ก˜  šฉ„ •œ‹ค. ธ๋ž˜„œ •ด๋‹น ๋น„šฉ€ ฐ ปดŒŒผ๋Ÿฌ๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค. ธ๋ƒฅ ๋Œ€ถฉ –ด๋ฆผžก•„„œ ˜ˆƒ•˜๋ฉด, ๋งŒ•ฝ try๋ธ”๋ก„ “ฐฒŒ๋˜๋ฉด, ๋‹‹ ˜  „ฒด ฝ”๋“œ ‚ฌฆˆ๋Š” 5-10%ฐ€ ๋Š˜–ด๋‚˜ , ๋‹‹ ˜ ‹–‰ ‹œ„ —ญ‹œ ๋น„Š•œ ˆ˜ค€œผ๋กœ ๋Š˜–ด๋‚œ‹ค.  œ •„๋ฌด๋Ÿฐ ˜ˆ™ธ๋ฅผ ๋˜ง€ง€ •Š๋Š”๋‹  ƒฐ•˜ž;šฐ๋ฆฌฐ€ —ฌธฐ—„œ † ๋ก •˜  žˆ๋Š”ฒƒ€ ๋‹ง€ ๋‹‹ ˜ ”„๋กœธ๋žจ๋‚ด—„œ tryฐ€ ฐ€ง€๋Š” ๋น„šฉ๋งŒ•„‹ˆ๋‹ค. ด๋Ÿฐ ๋น„šฉ˜ œ†Œ™”๋ฅผ œ„•„œ •„๋งˆ ๋‹‹ € •„š”•˜ง€ •Š๋Š” try๋ธ”๋Ÿญ€ ”ผ••ผ๋งŒ • ฒƒด๋‹ค.

ปดŒŒผ๋Ÿฌ๋Š” ˆ˜๋งฃ€ try ๋ธ”๋Ÿญ˜ ˜ˆ™ธ ŠคŽ™— ๋Œ€•œ ฝ”๋“œ๋ฅผ œ„•˜—ฌ ฝ”๋“œ๋ฅผ ๋งŒ๋“ค–ด๋‚ด••œ‹ค. ธ๋ž˜„œ ฝ”๋“œ ŠคŒฉ€ ผ๋ฐ˜ œผ๋กœ •˜๋‚˜˜ try๋ธ”๋Ÿญ๋‹ฐ™€ ˆ˜˜ ๋น„šฉ„ ง€œ•˜ฒŒ ๋œ‹ค. ž น?(excuse me?) ๋‹‹ € ˜ˆ™ธ ŠคŒฉด ๋‹‹œ ŠคŒฉธ, ฆ‰ ฝ”๋“œ๋ฅผ ๋งŒ๋“ค–ด ๋‚ด๋Š”ฑธ ƒฐ•˜ง€ •Š๋Š”๋‹  ๋ง•œ‹ค. ž, ๋‹‹œ€ ธ๋Ÿฐ ƒฐ— ด€•„œ กฐธˆ ƒˆ๋กœšด ๋ช‡ฐ€ง€๋ฅผ ฐ•ˆ•ด ๋ดใ….

๋ฌธ œ˜ ดˆ € ˜ˆ™ธฐ€ ๋˜ง€๋Š” ๋น„šฉด๋‹ค. ‚ฌ‹˜ˆ™ธ๋Š” €•œ ฒƒด๋ผ ๋ณดธฐ ๋•Œ๋ฌธ— ธ๋ ‡ฒŒ ฌฒŒ ฐ•ˆ•  ๋‚ดšฉ•„‹ˆ๋‹ค. ธ๋“ค˜ˆ™ธ (exceptional) ๋ฌธ œ˜(event) ๋ฐœƒ„ ง€นญ•—๋„ ๋ถˆตฌ•˜  ๋งด๋‹ค. 80-20 œน™€(Item 16—„œ –ธธ‰) šฐ๋ฆฌ—ฒŒ ธ๋Ÿฐ ด๋ฒคŠธ๋“ค€ ฑฐ˜ ”„๋กœธ๋žจ˜ ๋ถ€ณผ๋˜๋Š” „ฑ๋Šฅ— ปค๋‹ค๋ž€ ˜–ฅ„ ๋ฏธ˜ง€ •Š„ ฒƒด๋  ๋ง•œ‹ค. ธ๋Ÿผ—๋„ ๋ถˆตฌ•˜ , ๋‚˜๋Š” ๋‹‹ ด ๋ฌธ œ— ด€•˜—ฌ ˜ˆ™ธ๋ฅผ ๋˜ง€ , ๋ฐ›๋Š” ๋น„šฉ— ด€•œ ๋Œ€๋‹—„œ –ผ๋งˆ๋‚˜ ดนŒ๋ฅผ ถธˆ• ฒƒด๋  ƒฐ•œ‹ค. ๋Œ€• ผ๋ฐ˜ •ˆ˜˜ ๋ฐ˜™˜—„œ ˜ˆ™ธ๋ฅผ ๋˜„‹ค๋ฉด ๋Œ€ถฉ „œ˜ ๋ช…๋ –ด  •๋„ ๋” ๋А๋ ง€๋Š”(three order of magnitude) ฒƒด๋  ฐ€ •• ˆ˜ žˆ๋‹ค. •˜ง€๋งŒ ๋‹‹ € ฒƒ๋งŒ•„‹ฒƒด๋  •ธฐ • ฒƒด๋‹ค. ๋ฐ˜๋Œ€๋กœ‹‹ ด๋Ÿฐ ๋…ผŸ„ ๋ฐ„ตฌกฐ๋‚˜ ๋ฃจ”„˜ ˆœšŒ ตฌกฐ๋ฅผ šจœ œผ๋กœ ๋งŒ๋“œ๋Š”๋ฐ ‹ ฒฝ„ “ด๋‹ค๋ฉด ๋” ‹€ ‹œ„„ ๋ณด๋‚ด๋Š” ฒƒด๋  ƒฐ•œ‹ค.

ธ๋ ‡ง€๋งŒ ž น, ๋‚ดฐ€ ด๋Ÿฐฒƒ— ด€•„œ –ด๋–ปฒŒ •„๋ƒตฌ? ๋งŒ•˜ˆ™ธ๋ฅผ œ„•œ ง€›€ œ˜ ปดŒŒผ๋Ÿฌ™€ ใ„ปดŒŒผ๋Ÿฌ„— ๋‹ค๋ฅธ ๋ฐฉ‹œผ๋กœ „–‰๋œ‹ค๋ฉด„œ ๋น„šฉด 5-10%๋–จ–ดง€  Šค”ผ๋“œ —ญ‹œ ๋น„Š•˜ฒŒ ๋–จ–ดง€  „œ ๋ช…๋ –ด  •๋„ ๋Š˜–ด๋‚˜๋Š” ฒƒณผ ฐ™€ „ฑ๋Šฅ  €•˜— ด€•œ œ„˜ –ธธ‰ ด๋Ÿฐฒƒ— ด€•œ œ˜๋“ค? •„๋งˆ ๋‚ดฐ€ •„ˆ˜ žˆ๋Š” ๋‹ต๋ณ€€ ๋‹†Œ ๋†€๋ž„ฒƒด๋‹ค.:๋‹‹ ด try๋ธ”๋กณผ ˜ˆ™ธ ŠคŽ™„ ‚ฌšฉ„ •„š”•œ ณณ๋งŒ ‚ฌšฉ•˜๋„๋ก  œ•œ•ด๋ผ;ธ๋ฆฌ  ปดŒŒ•ด๋ด๋ผ, ธ๋ž˜๋„ „„ƒ— ๋ฌธ œฐ€ žˆ๋‹ค๋ฉด ผ๋‹ž‹ ˜ „„๋ฅผ ๋‹‹œ ธ๋ ค๋ณด  ƒฐ•ด ๋ณด๋ผ, ฑฐธฐ—๋‹ค, —ฌธฐ €ธฐ ๋‹ค๋ฅธ ๋ฒค๋”๋“ค˜ ปดŒŒผ๋Ÿฌ๋กœ ปดŒŒ•ด๋ด๋ธ๋Ÿผ •Œˆ˜ žˆ๋‹ค.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:49
Processing time 0.1069 sec