MoreEffectiveC++
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: ํ๊ดด์๋ก ๋ถํฐ์ ์์ธ ์ฒ๋ฆฌ๋ฅผ ๋ง์๋ผ.
๋ค์ ์์ ๋ 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์ ํธ๋์ ์ ์ ์ด์ฉํด์ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ชจ์ต์ด๋ค.
๋ฐ์ ์ฝ๋๋ 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: ๊ฐ์ ํจ์ ๋ถ๋ฅด๊ธฐ๋, ์ธ์ ์ ๋ฌ๋ก ์ฒ๋ฆฌ์ ์์ธ์ ๋ฌ์ ๋ฐฉ๋ฒ์ ์ฐจ์ด์ ์ ์ดํดํ๋ผ.
~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)๋ก ์ก์๋ผ.
์, ๋จผ์ 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: ์์ธ๋ฅผ ์ ์คํ๊ฒ ์ฌ์ฉํ๋ผ.
์ผ๋จ ์ด ์ฃผ์ ๋ฅผ ๋ถ์ ํ๋ ์ด๋ ์์ผ๋ฆฌ๋ผ.:์์ธ๋ ์ ์ ํ ๊ณณ์ ํํ๋์ด์ผ ํ๋ค. ๊ทธ๋ค์ ์ฝ๋๋ฅผ ๋ ์ดํด๊ฐ๊ธฐ ํธํ๊ฒ ๋ง๋ค์ด ์ค๋ค. ์๋ํ๋ฉด ์๋ง ๋ช
์์ ์ผ๋ก ํํ๋ ์์ธ ์ํ๊ฐ ์ ๋ฌ(๋์ :throw-์ดํ ๋์ง๋ค๋ ํํ์ผ๋ก) ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ ์ง๋ง ์์ธ๋ ์ฃผ์(comment)๋ณด๋ค๋ ๋ชจํธํ๋ค. ์ปดํ์ผ๋ฌ๋ ๋๋๋ก ์ปดํ์ผ์ค์ ์ ํํ ์ผ์นํ์ง ์์ ์์ธ๋ค์ ๋ฐ๊ฒฌํ ์๋ ์์ผ๋ฉฐ, ๋ง์ฝ ํจ์๊ฐ ์์ธ ์คํ(๋ช
์ธ:์ดํ๋ช
์ธ)์์ ์ ๋๋ก ๋ช
๊ธฐ๋์ง ์์ ์์ธ๋ฅผ ์ ๋ฌ(๋์ก)๋ค๋ฉด ์๋ชป์ ์คํ์๊ฐ(runtime)์ ๋ฐ๊ฒฌ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํน๋ณํ ํจ์์ธ unexpected๋ ์๋์ผ๋ก ๋ถ๋ฆฌ๊ฒ ๋๋ค. ์ด๋ ๋ ์์ธ์ฒ๋ฆฌ๋ ์๋นํ ๋งค๋ ฅ์ ์ธ ๋ฉด์ ๊ฐ์ง๊ณ ์๋ค.
- ํ์ง๋ง ๋ณดํต ์๋ฆ๋ค์์ ํ๋ฉด์ด ์๋ ๋ด๋ฉด์ ์กด์ฌํ๋ค.
๋ค์์ 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ํธ์ถ์ ๋ง๊ธฐ์ํ์ฌ ๋ถ์กฑํ ์์ธ ๋ช
์ธ์ ๊ท์ ์ผ๋ก ์ธํ์ฌ ๋ถ๋ฆฌ๋ ํจ์์์์ ์์ธ ๋ช
์ธ๋ฅผ ์๋ตํ ์ ์๋ค.
~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 ์์ธ๋ฅผ ๋ง๋ ์ ์๋ ๊ฐ๋ฅ์ฑ์ ๋ดํฌํ๋ ์
์ด๋ค.
๋ง์ฝ 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๋ก์ ๊ฒฐ๊ณผ๋ฌผ์ ๋ง๋ค์ด ๋ธ๋ค.
์ด์ ๋น์ ์ ์์ธ ๋ช ์ธ๊ฐ ๋ง์ ๋ฌธ์ ๋ฅผ ๊ฐ์ง๊ณ ์์์ ์์์ ์ดํด ํ ๊ฒ์ด๋ค. ์ปดํ์ผ๋ฌ๋ ๊ทธ๋ค์ ๋ถ๋ถ์ ์ธ ์ฐ์์๋ฅผ ๊ฒ์ฌํด์ ํ ํ๋ฆฟ์์ ๋ฌธ์ ๋ฅผ ๋ฐ์ํ ์์ง๋ฅผ ์์ผ๋ฉฐ, ์ปดํ์ผ๋ฌ๋ ์์ธ๋ก ๊ท์น์๋ฐ์ ํ๊ธฐ ์ฝ๊ณ , ์ปดํ์ผ๋ฌ๊ฐ ์ ๋๋ก ๋์ง ์์ผ๋ฉด ํ๋ก๊ทธ๋จ์ ๋ถ์์ ๋ฉ์ถ์ด ์ง๋๋ก ์ ๋ํ ๊ฒ์ด๋ค. ์์ธ ๋ช ์ธ ์ญ์ ๋๋ค๋ฅธ ๋ฌธ์ ๋ฅผ ์๊ณ ์๋๋ฐ, ์์ธ๋ช ์ธ๋ ๋์ ์์ค์ ํธ์ถ์๊ฐ ์์ธ ๋ฐ์์ ๋๋นํ ๋๋ 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: ์์ธ ํธ๋ค๋ง์ ๋ํ ๋น์ฉ ์ง๋ถ ๋ํ ์ดํด
์ ๊ทธ๋ผ ์ ํ ์์ธ ํธ๋ค๋ง์ ํ์ง ์์์๋์ ์ง๋ถ ๋น์ฉ์ ์๊ฐํด ๋ณด์, ๋น์ ์ ๊ฐ์ฒด๋ค์ด ์ ์ฌ๋๊ณ , ์ ์ง๋๋ ํธ๋์ด ํ์ํ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ฌ์ฉ์ ์ํด ๊ณต๊ฐ์ ๋ํ ๋น์ฉ ์ง๋ถ์ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋น์ ์ ์ด๋ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ค์ ๊ฐฑ์ ํ๊ณ ์ ์งํ๋๋ฐ ํ์ํ ์๊ฐ์ ๋ํ ๋น์ฉ์ ์ง๋ถํ๋ค. ์ด๋ฐ ๋น์ฉ๋ค์ ์ผ๋ฐ์ ์ผ๋ก ์ ๋นํ ์๊ตฌ์ด๋ค. ๋ฐ๋ฉด์ ํ๋ก๊ทธ๋จ์ด ์์ธ๋ฅผ ์ํ ์ง์์ด ์์ด ์ปดํ์ผ ๋๋ค๋ฉด ์์ธ ์ง์์ ํ๊ณ ์ปดํ์ผ ํ๋ ๋ฐ๋์ ๊ฒฝ์ฐ๋ณด๋ค ์ข๋ ๋น ๋ฅด๊ณ , ์ข๋ ์์ ์ฉ๋์ ์ฐจ์งํ๋ค.
์ด๋ก ์ ์ผ๋ก ๋น์ ์ ์ด๋ฐ(์์ธ) ๋น์ฉ์ ์ง์ถ(์ ํ,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๋ธ๋ก๊ณผ ์์ธ ์คํ์ ์ฌ์ฉ์ ํ์ํ ๊ณณ๋ง ์ฌ์ฉํ๋๋ก ์ ํํด๋ผ;๊ทธ๋ฆฌ๊ณ ์ปดํ์ผ ํด๋ด๋ผ, ๊ทธ๋๋ ์ค๊ณ์์ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ์ผ๋จ ์์ ์ ์ค๊ณ๋ฅผ ๋ค์ ๊ทธ๋ ค๋ณด๊ณ ์๊ฐํด ๋ณด๋ผ, ๊ฑฐ๊ธฐ์๋ค, ์ฌ๊ธฐ์ ๊ธฐ ๋ค๋ฅธ ๋ฒค๋๋ค์ ์ปดํ์ผ๋ฌ๋ก ์ปดํ์ผ ํด๋ด๋ผ ๊ทธ๋ผ ์์ ์๋ค.










