U E D R , A S I H C RSS

More EffectiveC++/Operator

1. Operator

1.1. Item 5: Be wary of user-defined conversion functions.

  • Item 5: ‚ฌšฉž  •˜ ˜•๋ณ€™˜(conversion) •ˆ˜— ฃผ˜•˜ผ!

  • C++๋Š” ƒ€ž…„˜ •”‹œ  type casting„ —ˆšฉ•œ‹ค. ฑด C˜ œ ‚ฐธ๋ฐ ˜ˆ๋ฅผ ๋“คž๋ฉด charณผ int —„œ shortณผ double ๋“ค•„๋ฌด๋Ÿฐ ๋ฌธ œ—†ด ๋ฐ”๋€Œ–ด „‹ค. ธ๋Ÿฐ๋ฐ C++๋Š” ฒƒ ๋ณด๋‹•œˆ˜ ๋”๋– „œ type casting‹œ— ž๋ฃŒ๋ฅผ žƒ–ด ๋ฒ„๋ฆฌฒŒ ๋˜๋Š” int—„œ shortณผ dougle—„œ char˜ ๋ณ€™˜นŒง€ —ˆšฉ•œ‹ค.

ผ๋‹ด๋Ÿฐ ธฐ๋ณธ ๋ณ€™˜— ๋Œ€•„œ œ๋ฐœž๋Š” –ดฐŒ ด€—ฌ • ˆ˜ —†๋‹ค. •˜ง€๋งŒ, C++—„œ class˜ ˜•๋ณ€™˜€ œ๋ฐœžฐ€ ˜•๋ณ€™˜— ด€•˜—ฌ ด€—ฌ• ˆ˜ žˆ๋‹ค. ๋ณ€™˜— ด€•˜—ฌ ๋…ผ•œ‹ค.

  • C++—„œ๋Š” ฌฒŒ ๋‘ฐ€ง€ ๋ฐฉ‹˜ •ˆ˜๋กœ ˜•๋ณ€™˜„ ปดŒŒผ๋Ÿฌ—ฒŒ ˆ˜–‰ ‹œ‚ค‚จ๋‹ค:
    single-argument constructors ™€ implicit type conversion operators ฒƒด๋‹ค.
  • single-argument constructors € ž๋ฅผ •˜๋‚˜˜ ž๋งŒœผ๋กœ „Œ…๋ ˆ˜ žˆ๋Š” ƒ„žด๋‹ค. —ฌธฐ ๋‘ฐ€ง€˜ ˜ˆ๋ฅผ ๋ณดž

~cpp 
class Name {
public:
    Name( const string& s);
    ...
};
class Rational {
public:
    Rational( int numerator = 0, int denominator = 1);
    ...
};

  • implicit type conversion operator € ด๋ž˜Šค๋กœ •˜—ฌธˆ •ด๋‹ƒ€ž…œผ๋กœ return „ ›• •Œ •”‹œ ธ ๋ณ€™”๋ฅผ ง€›•˜ธฐ œ„•œ operatorด๋‹ค. •„๋ž˜๋Š” double๋กœ˜ ˜•๋ณ€™˜„ œ„•œ ฒƒด๋‹ค.

~cpp 
class Rational{
public:
    ...
    operator double() const;
};

Rational r(1,2);
dougle d = 0.5 * r;
ฐธ œฐฎ€ ๋ฐฉ๋ฒ•ด๋‹ค. •˜ง€๋งŒ ด ๋ฐฉ๋ฒ•€ œ๋ฐœžฐ€ ˜๋„•˜ง€ •Š€ ˜•๋ณ€™˜๋งˆ ‹œ‚ค๋Š” ฒƒ๋•Œ๋ฌธ— ๋ฌธ œฐ€ ๋ฐœƒ•œ‹ค. ๋‹Œ„ ๋ณดž
~cpp 
Rational (1,2);
cout << r;      // should print "1/2"
operator<<๋Š” ˜Œ Raional ด๋ผ๋Š” ˜•— ๋Œ€•œ ž‹ ˜ ๋Œ€‘„ ฐพง€๋งŒ —† , ด๋ฒˆ—๋Š” r„ operator<<ฐ€ ˜๋ฆฌ• ˆ˜ žˆ๋Š” ˜•œผ๋กœ ๋ณ€™˜‹œ‚ค๋ ค๋Š” ž‘—…„ •œ‹ค. ธ๋Ÿฌ๋Š” ™€‘— r€ double๋กœ •”‹œ  ๋ณ€™˜ด๋ฃจ–ด ง€  ฒฐณผ double ˜•œผ๋กœ œ ด ๋œ‹ค.

๋ญ ด๋Ÿฐ •”‹œ  ˜•๋ณ€™˜„ ๋ง‰„ ค๋ฉด, ˜• „™˜ ‹œ‚ค  •˜๋Š” •”‹œ  ‚ฌšฉ„ •˜ง€ •Š , ๋‹ค๋ฅธ •ˆ˜๋กœ ๋ช…‹œ œผ๋กœ •„ˆ˜ žˆ๋‹ค.
~cpp 

class Raional{
public:
    ...
    double asDouble() const;
};

Rational r(1,2);
cout << r;                // error!
cout << r.asDouble();     // double๋กœ˜  „™˜˜ ˜๋„ฐ€ ™•‹žˆ  „•„‹ค.

ด๋Ÿฐ ˜ˆ๋กœ C++ std library— žˆ๋Š” stringด char*๋กœ •”‹œ  ˜•๋ณ€™˜—†  c_str˜ ๋ช…‹œ  ˜•๋ณ€™˜ ‹œ‚จ๋‹ค.

  • single-argument constructor ๋Š” ๋” –ด๋ šด ๋ฌธ œ๋ฅผ  œณต•œ‹ค. ฒŒ๋‹ฐ€ ด๋ฌธ œ๋“ค€ •”‹œ  ˜•๋ณ€™˜ ๋ณด๋‹ค ๋” ๋งŽ€ ๋ถ€๋ถ„„ ฐจง€•˜๋Š” •”‹œ  ˜•๋ณ€™˜—„œ ๋ฌธ œฐ€ ๋ฐœƒ๋œ‹ค.

~cpp 
template<class T>
class Array{
public:
    Array ( int lowBound, int highBound );
    Array ( int size )

    T& operator[] (int index)
    ...
};

ฒซ๋ฒˆงธ ƒ„ž๋Š” ๋ฐฐ—ด˜ lowBound~highBound ‚ฌด๋กœ˜ ฌธฐ  œ•œž , ๋‘๋ฒˆงธ ƒ„ž๋Š” •ด๋‹ฌธฐ๋กœ ๋ฐฐ—ด ณต„ ƒ„ธ๋ฐ, ด ๋‘๋ฒˆงธ˜ ƒ„žฐ€ ˜•๋ณ€™˜„ ฐ€๋Šฅ•˜ฒŒ ๋งŒ๋“ค–ด„œ ๋ฌด•œ•œ ‚ฝงˆ— „„— ๋‹‹ „ ดˆ๋Œ€•œ‹ค. (‹ œ๋กœ ด๋Ÿฐ ˜๋ฏธ๋กœ จžˆ๋‹ค. --ƒ๋ฏผ)

˜ˆ๋ฅผ ๋“ค–ด„œ‹Œ„ ๋ณดž
~cpp 
bool operator==( const Array< int >& lhs, const Array<int>& rhs);

Array<int> a(10);
Array<int> b(10);
...
for ( int i = 0; i<10; ++i)
    if( a == b[i] ) {           // —‰Šค! ด๋Ÿฐ "a"๋Š” "a[i]" จ••  ฝ”๋“œ˜€๋‹ค!. (œ๋ฐœž˜ ‹ˆ˜ ˜๋ฏธ, •œ๋ฏธ –‘ตญ—„œ ฐ™€ ๋ฐœŒ˜ oops! --;;  --ƒ๋ฏผ)
        a[i]™€ b[i]ฐ€ ฐ™„•Œ ฝ”๋“œ๋ฅผ ˆ˜–‰•œ‹ค.;
    }
    else {
        œ„˜ กฐฑด„ ๋งŒกฑ•˜ง€ ๋ชป•˜๋ฉด ฝ”๋“œ๋ฅผ ˆ˜–‰•œ‹ค.;
    }
7„ if ( a == bi ) ๋ถ€๋ถ„˜ ฝ”๋“œ—„œ ”„๋กœธ๋ž˜๋จธ๋Š” ž‹ ˜ ˜๋„™€๋Š” ๋‹ค๋ฅธ ฝ”๋“œ๋ฅผ ž‘„–ˆ๋‹ค. ด๋Ÿฐ ๋ฌธ๋ฒ• ž˜๋ชป€ ๋‹—ฐžˆ! ปดŒŒผ๋Ÿฌฐ€ •Œ๋ ˜•œ๋ฐœž˜ ‹œ„„ •„๋‚„ˆ˜ žˆœผ๋ฆฌ, •˜ง€๋งŒ ด๋Ÿฐ ˜ˆ œฐ€ ผญ ธ๋ ‡ง€๋งŒ€ •Š๋‹ค. ฝ”๋“œ๋Š” ปดŒŒผ๋Ÿฌ ž…žฅ—„œ ๋ณด๋ฉด ˜€ ฝ”๋“œฐ€ ๋ ˆ˜ žˆ๋Š” ฒƒด๋‹ค. ๋ฐ”๋กœ Array class—„œ  •˜ •˜  žˆ๋Š” single-argument constructor — ˜•˜—ฌ ปดŒŒ‹œ ด๋Ÿฐ ฝ”๋“œ๋กœ˜ ๋ณ€™˜˜ ฐ€๋Šฅ„žˆ๋‹ค.

~cpp 
for ( int i = 0; i < 10; ++i)
    if ( a == static_cast< Array<int> >(b[i]) )...
bi ๋Š” int˜•„ ๋ฐ˜™˜•˜ธฐ ๋•Œ๋ฌธ— ด๋ ‡ฒŒ ฆ‰„—„œ ๋งžถค ƒ„ž๋กœ type casting(˜•๋ณ€™˜)„ ปดŒŒผ๋Ÿฌฐ€ •”‹œ œผ๋กœ •„ˆ˜ žˆ๋‹ค.  œ ‚ฌƒœ˜ ‹ฐ„„ •Œ ๋Š”ฐ€?

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

~cpp 
template<class T>
class Array{
public:
    ...
    expicit Array ( int size )   
    ...
};

Array<int> a (10); 
Array<int> b (10);       // ๋‘œ ๋ชจ๋‘ ƒ„ฐ€๋Šฅ•˜‹ค

if ( a == Array<int>(b[p])) ...                  // ฝ”๋“œ —ญ‹œ ˜ฌ๋ฐ”๋ฅด๋‹ค. 
                                                 // •˜ง€๋งŒ ๋‹ค๋ฅธ œ๋ฐœžฐ€ •„— ‚ฌšฉž˜ ˜๋„ฐ€ •„ ˜๋ฌธ„‹ค.
if ( a == static_cast< Array<int> >(b[p])) ...   // ๋งž๋‹ค. œ„™€ ๋งˆฐฌฐ€ง€๋กœ‹ค๋ฅธ ‚ฌ๋žŒด ๋•€˜๋ฆฐ๋‹ค
if ( a == (Array<int>) b[i] )                    // C-style ˜ ˜•๋ณ€™˜ธ๋ฐ —ญ‹œ๋‚˜‹ค๋ฅธ‚ฌ๋žŒ—ด๋ฐ›๋Š”๋‹ค.
ด๋ ‡ฒŒ explicit๋ฅผ ‚ฌšฉ•˜๋ฉด ๋ช…‹œ œผ๋กœ๋งŒ ˜•๋ณ€™˜ฐ€๋Šฅ•˜‹ค. •˜ง€๋งŒ ๋˜ •˜๋‚˜ ๋ฌธ๋ฒ•ƒ œ ˜ ••• ‚ฌ•€
~cpp 
static_cast< Array<int> >(b[p])
ตฌ๋ถ„—„œ > > ด ๋‘œ๋ฅผ ๋ถ™—ฌ“ฐ๋ฉด >> operator๋กœ •„•˜‹ˆ œ ˜•ด๋

—ฌธฐ— •œฐ€ง€ ๋” ƒฐ•ด ๋ณดž.

๋งŒ•ฝ ๋‹‹ ˜ ปดŒŒผ๋Ÿฌฐ€ —„ฒญ ๋‚ก€ ฑฐฑฐ๋‚˜  œž‘žฐ€ œ๋นก•„œ, ˜€ explicit๋ฅผ ฃฝ–ด๋„„ธฐ ‹ซ๋‹  • •Œ—๋Š”?

—ฌธฐ— ๋‚˜˜จ Array ˜ˆ œ๋ฅผ •œ๋ฒˆ  ณ„œ ๋งˆ˜ explicit ๋ฅผ “ดฒƒ˜๋Ÿผ •ด๋ณดž
~cpp 
template<class T>
class Array{
public:
    class ArraySize{
    public:
        ArraySize(int numElements):theSize(numElements){}
        int size() const { return theSize; }
    private:
        int theSize;
    }
    Array( int lowBound, int highBound);
    Array( ArraySize size );                      // ƒˆ๋กœšด „ –ธ!
    ...
}

ด๋ ‡ฒŒ Array •ˆชฝ— ArraySize ๋ฅผ „ –ธ•˜  publicœผ๋กœ ๋ถˆ–ด„œ ด๋ ‡ฒŒ ƒ„•˜๋ฉด
~cpp 
Array<int> a(10);

ปดŒŒผ๋Ÿฌ ๋‹—„œ aƒ„žธ Array( ArraySize size) —„œ ArraySize ๋กœ˜ single-argument constructor๋ฅผ ˜œ•˜ธฐ ๋•Œ๋ฌธ— „ –ธฐ€๋Šฅ•˜ง€๋งŒ
~cpp 
bool operator==( const Array< int >& lhs, const Array<int>& rhs);

Array<int> a(10);
Array<int> b(10);
...
for ( int i = 0; i<10; ++i)
    if( a == b[i] ) 
ด๋Ÿฐ ฒฝšฐ— operator==˜ ˜ค๋ฅธชฝ— žˆ๋Š” ž๋Š” intฐ€ single-argument constructor— ฑฐ ˆ˜ —†ธฐ ๋•Œ๋ฌธ— —๋Ÿฌ๋ฅผ ๋ฐ–ด ๋‚ธ๋‹ค.

*›„ธฐ:ด๋ฒˆป€ ๋„ˆ๋ฌด ธธ๋‹ค. ๋‹ค๋ฅธฑฐ— ๋‘๋ฐฐ— •ด๋‹•˜๋Š”ฑฐ ฐ™€๋ฐ ๋‹Œ๋ถ€„ฐ๋Š” ๋”ดฒญ ”ผšฐง€ ๋ง  ••ง€ --ƒ๋ฏผ

1.2. Item 6: Distinguish between prefix and postfix forms of increment and decrement operators.

  • Item 6: prefix™€ postfix๋กœ˜ ฐ —ฐ‚ฐž ตฌ๋ถ„•˜ผ!

šฐ๋ฆฌ๋Š” ++™€ --—ฐ‚ฐž(•˜ ฐ€นญ ฐ€ฐ —ฐ‚ฐž)๋ฅผ ฆฒจ “ด๋‹ค. —ฐ‚ฐž —ญ‹œ ด๋ž˜Šค—„œ  •˜•„œ ‚ฌšฉ• ˆ˜ žˆ๋‹ค.
•˜ง€๋งŒ ฐ€ฐ —ฐ‚ฐž๋Š” ๋‘ฐ€ง€๋กœ ๋‚˜๋‰œ‹ค๋Š” ‚ฌ‹„ ƒฐ•˜๋ฉด ‘žธฐ ๋‚œฐ•„‹ค. „ค๋งˆ „„žฐ€ ธ๋Ÿฐ ๋‹จ!ˆœ!•œ! ๋ฌธ œ๋ฅผ „ณผ• ๋ฆฌ —†๋‹ค.

~cpp 
class UPInt{  //๋ฌด•œ  •ˆ˜˜•
public:
    UPInt& opertrator++(int);         // prefix++
    const UPInt operator++(int);      // postfix++

    UPInt& opertrator--(int);         // prefix--
    const UPInt operator--(int);      // postfix--

    UPInt& operator+=(int);           // a += operator ๋Š” UPInt™€ ints ถ”ฐ€ œ„•ด
...
};
UPInt i;

++i;        // i.operator++();
i++;        // i.operator++(0);

--i;        // i.operator--();
i--;        // i.operator--(0);

๋ณด  žˆž๋ฉด  •๋ง •„ด๋””–ด œฐฎ€๋“ฏ ธ๋Ÿผ ตฌฒด ตฌ˜„๋ถ€— ด€•„œ „‹žˆ ๋…ผ•œ‹ค.
~cpp 
// prefix ฐ€ —ฐ‚ฐž ๋ถ€๋ถ„ณผ fetch
UPInt& UPInt::operator++()
{
    *this += 1;       // ฐ€
    return *this      // fetch!
}

// postfix ฐ€ —ฐ‚ฐž ๋ถ€๋ถ„ณผ fetch
const UPInt& UPInt::operator++(int)
{
    UPInt oldValue = *this;             // fetch
    ++(*this);                          // prefix ฐ€ ‹œ‚จ๋‹ค.
    return oldValue;
}

*ž‘„ž ‚ฌ„ค: •„ ๋‚˜๋Š”  •๋ง ด๋Ÿฐ ๋ฆฌ„•ฐ€ •ˆ„‹ค. ฐธกฐ๋กœ„˜ฒจ ๋ฒ„๋ฆฌ๋ฉด ๋Œ€ฒด ปดŒŒผ๋Ÿฌ๋Š” –ด๋А ‹œ —„œ oldValue˜ ŒŒดด๋ฅผ •˜๋ƒ” ๋งด๋‹ค. C++ด reference countingœผ๋กœ ž› ด€๋ฆฌ๋ฅผ ๋”ฐ๋กœ •ฃผ๋Š” ฒƒ๋„ •„‹Œ๋Œ€ ๋งด๋‹ค. 1•™๋…„•Œ ๋ถ€„˜  ๋ฏผด๋‹จ ๋งด๋‹ค. ข€ ๋ช…พŒ•œ „ค๋ช…„ ๋ˆ„ฐ€ •คฌœผ๋ฉด..

•”Šผ  € œ„™€ ฐ™•˜๋ฉด •ฐ€ ฐˆฒƒด๋‹ค. •˜ง€๋งŒ ด๋Ÿด ฒฝšฐ š” ง“ฑฐ๋ฆฌ๋ฅผ ๋ชป•œ‹ค.

~cpp 
    UPint i;
    i++++;                 
˜๋ฏธ๋Š”
~cpp 
    i.operator++(0).operator++(0);
ณผ ฐ™๋‹ค. ๋‹—ฐžˆ •ˆ๋˜ ง€?

  • ž‘„ž ‚ฌ„ค:๋ณธ๋ฌธ—„œ๋Š” ธ ๋’ค๋ถ€„ฐ๋Š” •„˜ˆ ด๋Ÿฐฑธ “ฐง€ ๋งž๋Š” •„š”„˜ –ธธ‰๋‹ˆ๋‹ค. ฐจ›„ ถ”ฐ€˜ •„š”„žˆ„•Œ ถ”ฐ€•ฉ๋‹ˆ๋‹ค.
    ธ๋ƒฅ i++ ๋‘๋ฒˆ “ฐ  ๋งง€..

1.3. Item 7: Never overload &&, ||, or ,.

  • Item 7:  ˆ๋Œ€๋กœ! &&, ||, ',' —ฐ‚ฐž๋“ค„ overload •˜ง€ ๋ง•„


~cpp 
    char *p;
    ...
    if ((p != 0) && (strlen(p) > 10) ) ...
œ„˜ ฝ”๋“œ—„œ๋Š” strlen() •ˆ˜๋‚ด๋ถ€—„œ p— ด€๋ •œ null pointer ฒ€‚ฌฐ€ •„š”•˜ง€ •Š๋‹ค. ™œ๋ƒ•˜๋ฉด && —„œ๋Š” •ž˜ กฐฑดด ๋ถ€ • ฆ‰, ( false && anything ) ˜ ฒฝšฐ—๋Š” ๋’ค˜ กฐฑด(anything)€ ˆ˜–‰กฐฐจ •ˆ•˜ธฐ ๋•Œ๋ฌธด๋‹ค. operator ||˜ ฒฝšฐ๋„ Šน • กฐฑด—„œ,(true || anything) ๋’ค— ฝ”๋“œ๋ฅผ ˆ˜–‰•˜ง€ •Š€๋‹ค๋Š” ฒƒ€ ๋น„Š•˜‹ค.
~cpp 
    int rangeCheck( int index)
    {
        if ((index < lowerBound) || (index > upperBound)) ...
        ...
    }

ˆ˜๋งŽ€ œ๋ฐœž๋“คด๋Ÿฐ ๋‹ˆœ•œ ›๋ฆฌ๋ฅผ ”„๋กœธ๋žจ ƒ—„œ˜ งง€ „–‰(short-circuit)„ ถ”ตฌ•˜๋Š”๋ฐ ‚ฌšฉ•˜˜€๋‹ค. ธ๋ ‡๋‹ค๋ฉด C++—„œ˜ ฒด๋“ค—ฒŒ operator ||, && ๋ฅผ overload ‹œ‚ค๋ฉด งง€ „–‰„ ถ”ตฌ•˜๋Š”๋ฐ ๋„›€ด ๋˜ง€ •Š„นŒ? ธ๋Ÿฐ๋ฐ •˜ง€ ๋ง๋ผ๋‹ˆ ™œนŒ?

ผ๋‹จ operator &&, ||๋Š” ด๋ ‡ฒŒ ๋‘ฐ€ง€˜ ฒฝšฐ๋กœ‘˜๋ฆดˆ˜ žˆ๋‹ค.
~cpp 
    if (expression1 && expression2) ...
ด ๋ฌธžฅ˜ •„„ ปดŒŒผ๋Ÿฌ๋Š” ด๋ ‡ฒŒ ๋ฐ›•„ ๋“คธ๋‹ค.
~cpp 
    1. if (expression1.operator&&(expression2))...   // when operator && is member function.
    2. if (operator&&(expression1 , expression2))... // global function

ž ด ๋‘ฒฝšฐ ๋ชจ๋‘๋ฅผ ƒฐ•ด ๋ณด๋ฉด 1,2 –‘ชฝ ๋‹ค expression1, expression2 ˜ ฒฐณผ ฐ’•„š”•œ ƒ™ฉด๋‹ค. ฆ‰, operator && ๋‚˜ operator || ˜ ฒฝšฐ –‘ชฝด classž๋“ , –ด๋–ค ˜•ƒœด๋“  ๋ฐ˜๋“œ‹œ ฒฐณผ ฐ’•„š”•˜‹ค. œ„—๋„ –ธธ‰–ˆง€๋งŒ, ด๋ฏธ ๋งŽ€ œ๋ฐœž๋“คด &&™€ ||˜ Šน„„ ž˜ •Œ  ‚ฌšฉ•˜  žˆœผ๋ฉฐ, operator &&, ||˜ overload๋Š” ตฌ๋™๋˜ง€ ๋ง•„••  ฝ”๋“œฐ€ ตฌ๋™๋˜๋Š” ˜๋„•˜ง€ •Š€ ˜ค๋ฅ˜ฐ€ ๋ฐœƒ †Œง€ฐ€ žˆ๋‹ค.

"comma operator" —ญ‹œ ๋งˆฐฌฐ€ง€๋‹ค. comma operatorฐ€ ๋Œ€ฒด ๋ญ๋ƒ ?

comma operator๋Š” ‘œ˜„(form expression)— ‚ฌšฉ๋œ‹ค. •„๋ž˜๋ฅผ ๋ณดž
~cpp 
void reverse(char s[])
{
    for (int i = 0, j = strlen(s)-1;
        i < j;
        ++i, --j)                   // ด๋…€„๋“คด ๋ฐ”๋กœ comma operator๋“คด๋‹ค. ธฐฐ€ ๋ง‰˜€..
    {
        int c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}
ฒฐ๋ก € overload๋กœ –ธ–ดƒ˜ ด๋…€„๋“ค ›๋ž˜˜ ๋Šฅ๋ ฅ ๋ฐœœ˜•˜ธฐฐ€ ž˜๋“ค๋‹ค. ด๋Ÿฐ œ„—˜€ ฐˆ˜•  •„š” —†ง€ •Š€ฐ€? ฐธ ๋กœ‹Œ„ •Œž

overload• ˆ˜ —†๋Š” operator
~cpp 
    .                .*                ::                ?:
    new              delete            sizeof            typeid
    static_cast      dynamic_cast      const_cast        reinterpret_cast
overlod • ˆ˜ žˆ๋Š” operator
~cpp 
    operator new     operator delete
    operator new[]   operator delete[]
    +    -    *    /    %    ^    &    |    ~
    !    =    >    <    +=   -=   *=   /=   &=
    ^=   &=   |=   <<   >>   >>=  <<=  ==   !=
    <=   >=   &&   ||   ++   --   ,    ->*  ->
    ()   []

1.4. Item 8: Understand the differend meanings of new and delete

  • Item 8: new™€ deleteฐ€ “ฐž„— ๋”ฐ๋ฅธ ˜๋ฏธ๋“ค˜ ฐจด๋ฅผ ••˜ผ.

๋ณด†ต C++—„œ šฉ–ด๋“ค„  •™•žˆ •ด ๋ชป•  ฒฝšฐฐ€ žˆ๋‹ค. ๋ฐ”๋กœ newoperator™€ operator newฐ€ ธ ๋Œ€‘œ ˜ˆฐ€ ๋ ˆ˜žˆ„ ฒƒด๋‹ค. ๋‹Œ˜ ฝ”๋“œ๋ฅผ ๋ณดž
~cpp 
    string *ps = new string("Memory Management");

ฝ”๋“œ๋Š” new operator๋ฅผ ‚ฌšฉ•œ ฒƒด๋‹ค. new operator๋Š” sizeof ˜๋Ÿผ –ธ–ด ƒ— ฌ•จ๋˜–ด žˆœผ๋ฉฐ, œ๋ฐœžฐ€ ๋” ƒ ˜๋ฏธ˜ ๋ณ€ฒฝด ๋ถˆฐ€๋Šฅ•˜‹ค. ฑด ๋‘ฐ€ง€˜ —ญ• „ •˜๋Š”๋ฐ, ฒซงธ๋กœ •ด๋‹ฒดฐ€ ๋“ค–ดฐˆ ๋งŒ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ • ‹•˜๋Š” ฒƒ , ๋‘˜งธ๋กœ •ด๋‹ฒด˜ ƒ„ž๋ฅผ ๋ถˆ๋Ÿฌฃผ๋Š” —ญ• ด๋‹ค. new operator๋Š” •ƒ ด ๋‘ฐ€ง€˜ ˜๋ฏธ๋ž‘๋™•˜๋ฉฐ •ž—„œ –ธธ‰•œ๋“ฏ ๋ณ€ฒฝ€ ๋ถˆฐ€๋Šฅ•˜‹ค.

๋ณด†ต operator new๋Š” ด๋ ‡ฒŒ „ –ธ๋˜–ด žˆ๋‹ค.
~cpp 
    void * operator new(size_t size);
ฑด ณผฑฐ C—„œ˜ malloc˜๋Ÿผ ดˆธฐ™” ๋˜ง€ •Š€ size๋งŒผ˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ • ‹•„œ ฑธ ฐ€๋ฆฌ‚ค๋Š” void˜•˜ pointer๋ฅผ ๋Œ๋ ฃผ๋Š” ฒƒด๋  ˜ˆธก• ˆ˜ žˆ ‹ค.(๋งž๋‹ค) œ๋ฐœž๋Š” operator new๋ฅผ overload• ˆ˜ žˆง€๋งŒ ฒซ๋ฒˆงธ ž๋Š” •ƒ size_tฐ€ ๋˜–ด••œ‹ค.

•„๋งˆ —ฌ๋Ÿฌ๋ถ„€ operator new๋ฅผ ง ‘ ๋ถ€๋ฅด๋Š”ฑธ ฒฐฝ” ›•˜ง€ •Š ง€๋งŒ(ƒ„ž, ŒŒดดž๋ฅผ ƒฐ•ด ๋ณด๋ฉด ๋งง€), จ๋จน„ˆ˜ žˆ๋Š”๋ฐ •œ๋ฒˆ •ด๋ณดž.
~cpp 
    void *rawMemory = operator new(sizeof(string));

string ฒดฐ€ •„š”๋กœ •˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋งŒผ• ‹น๋œ‹ค. •˜ง€๋งŒ œ„˜ ˜๋ฏธ˜๋Ÿผ malloc, operator new๋Š” ƒ„ž๋ฅผ ˜œ•˜ง€๋Š” •–๋Š”๋‹ค. ƒ„ž˜ ˜œ€ new operator ๋ชซด๋‹ค.

new operator๋ฅผ ๋ณด๋ฉด
~cpp 
    string *ps = new string("Memory Management");
‹Œณผ ฐ™€ ฝ”๋“œ๋Š” ปดŒŒผ๋Ÿฌ ๋‹—„œ ด๋ ‡ฒŒ ตฒด๋œ‹  ๋ณผˆ˜ žˆ๋‹ค.
~cpp 
    void *memory = operator new(sizeof(string));

    call string::string("Memory Management") on *memory;

    string *ps = static_cast<string*>(memory);

•ด๋‹ฝ”๋“œ‘๋ฒˆงธ ๋ถ€๋ถ„˜ ƒ„ž ˜œ„ ๋ˆˆ—ฌฒจ ๋ด๋ผ.

  • Placement new
‹‹ € ƒ„ž๋ฅผ ง ‘ ˜œ•˜ธฐ๋ฅผ ›• •Œฐ€ žˆ„ ฒƒด๋‹ค. •˜ง€๋งŒ ƒ„ž๋Š” ฒด(object)๋ฅผ ดˆธฐ™” ‹œ‚ค ,  œ(object)๋Š” ˜ง ˜Œ ฃผ–ดง€๋Š” ๋‹•œ๋ฒˆ˜ ฐ’œผ๋กœ ดˆธฐ™” ๋˜–ด งˆˆ˜žˆธฐ ๋•Œ๋ฌธ— (˜ˆ-const ˆ˜๋“ค ดˆธฐ™”— ดˆธฐ™” ๋ฆฌŠคŠธ๋ฅผ “ฐ๋Š” ฒฝšฐ) ƒ„ž๋ฅผ ด๋ฏธ กดžฌ•˜  žˆ๋Š” ฒด— ˜œ•œ‹ค๋Š”ฑด ƒฐ˜ —ฌง€ฐ€ —†„ ฒƒด๋‹ค.

ธ๋ ‡ง€๋งŒ —ฌ๋Ÿฌ๋ถ„ด raw memory๋กœ ฒด๋ฅผ • ‹•œ‹ค๋ฉด ดˆธฐ™” ๋ฃจ‹•„š”•˜‹ค.

(—ฌ๋‹ด-›„›„ ๋‚˜๋„ ƒ๋‹˜ operator new๋ฅผ ๋ณด๋Š” ˆœ„ ƒฐ–ˆ๋‹ค.)

๋ฐ”๋กœ operator new˜ Šน™” ๋ฒ„ „placement new๋กœ • ˆ˜ žˆ๋‹ค.

‹Œ€ placement new๋ฅผ ‚ฌšฉ•œ ˜ˆ œด๋‹ค.
~cpp 
    cass Widget {
        public:
            Widget(int widgetSize);
            ...
    };
    Widget* constructWidgetInBuffer(void * buffer, int widgetSize)
    {
        return new(buffer) Widget(widgetSize);
    }

•ด๋‹•ˆ˜(construcWidgetInBuffer())๋Š” ๋ฒ„ผ— ๋งŒ๋“ค–ด„ Widget ฒด˜ ฌ„ฐ๋ฅผ ๋ฐ˜™˜•˜—ฌ ค€๋‹ค. ด๋ ‡ฒŒ ˜œ•  ฒฝšฐ ฒด๋ฅผ ž„˜ œ„˜— • ‹• ˆ˜ žˆ๋Š” ๋Šฅ๋ ฅ ๋•Œ๋ฌธ— shared memory๋‚˜ memory-mapped I/O ตฌ˜„— šฉ•˜‹ค constructorWidget— ๋ณดด๋Š”ฑด ๋ฐ”๋กœ
~cpp 
    return new (buffer) Widget(widgetSize);
ด ๋ฌธธ๋ฐ , •„๋งˆ ˜Œ ๋ณดธฐ— ƒ†Œ•  ฒƒด๋‹ค. ž„žˆ ๋œ–ด ๋ณด๋ฉด, (buffer)— ˜•„œ •”‹œ œผ๋กœ new๋Š” operator new๋กœ ˜œ๋˜–ด „‹ค. ๋ง๋ถ™—ฌ, •„๋ž˜˜ void*๋Š” ๋ฉ”๋ชจ๋ฆฌ ƒ˜ œ„˜๋ฅผ size_t๋Š” ๋ฉ”๋ชจ๋ฆฌƒ ฒดฐ€ ฐจง€•˜๋Š” ˜—ญด๋‹ค. ž, œ„™€ ๋น„ต•ด ๋ณด๋ด operator๋Š” new๋ฅผ overload•œ ๋ฒ„ „ด๋‹ค.
~cpp 
    void* operator new(size_t, void *location)
    {
        return location;
    }

ฑฐ „‹žˆ ๋ณดง€๋งŒ placement new˜  „๋ถ€ด๋‹ค. operator new˜ —ญ• € •ด๋‹ฒด๋ฅผ œ„•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ฐพ (• ‹น), •ด๋‹ฌ„˜ ๋ฐ˜™˜  placement new˜ ฒฝšฐ—๋Š” ˜œžฐ€ ด๋ฏธ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ™•๋ณด•˜˜€ , ๋‹ˆœžˆ ฌ„ฐ ๋ฐ˜™˜๋งŒ •ค€๋‹ค. ๋ชจ๋“  placement newฐ€ ๋ฐ˜๋“œ‹œ ด๋Ÿฐ pointer˜  „‹—ญ• „ •œ‹ค. ธ๋ฆฌ  size_t žฐ€ •„๋ฌด๋Ÿฐ ด๋ฆ„—†–ด๋„ ๋ฐ˜••ˆ•œ‹ค. ž„•œฑด Item 6„ ๋ณด๋ฉด •ฐ€ ฐˆฒƒด๋‹ค.

ด๋Ÿฐ placement new๋Š” C++ ‘œค€ ๋ด๋ธŒ๋Ÿฌ๋ฆฌ˜ •œ ๋ถ€๋ถ„œผ๋กœ placement new๋ฅผ “ฐ ž •œ‹ค๋ฉด #include<new> ๋ฅผ •ฃผ๋ฉด ๋œ‹ค.

  • new ฒฐ๋ก !
žž new ฒฐ๋ก ด๋‹ค.

the new operator : heap ๋ฉ”๋ชจ๋ฆฌ ™•๋ณด™€ ƒ„ž ˜œ ๋™‹œ—

operator new : •ด๋‹ฒด˜ ๋ฉ”๋ชจ๋ฆฌ ™•๋ณด๋งŒ

placement new : ด๋ฏธ ™•๋ณด ๋ฉ”๋ชจ๋ฆฌฐ€ กดžฌ•˜  ฒด ดˆธฐ™”๋ฅผ ›•œ‹ค๋ฉด

ด๋‹–ด„”„ฒŒ  •๋ฆฌ–ˆ  ฐจ›„ ถ”ฐ€ • ฒƒด๋‹ค.

  • Deletion and Memory Deallocation
๋™  • ‹— ๋Œ€•˜—ฌ ๋ฆฌ†ŒŠค ƒˆ๋Š”ฑธ ๋ฐฉง€•  ค๋ฉด •ด๋‹น ๋™  • ‹— ƒ‘•˜๋Š” ‘•(?)•„𔕠 ฒƒด๋‹ค. ˜ˆ๋ฅผ๋“ค–ด„œ new๋‚˜ operator new—๋Š” ด๋Ÿฐฑฐ
~cpp 
    string *ps;
    ...
    delete ps;      // delete operator ๋ฅผ ‚ฌšฉ•œ‹ค.
‹‹ “ฐ  žˆ๋Š” ปดŒŒผ๋Ÿฌ๋Š” ฒด ps point๋ฅผ ŒŒดด•˜  ฒดฐ€ ฐ€ง€  žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ • œ•œ‹ค.

๋ฉ”๋ชจ๋ฆฌ • œ(deallocaion)€ operator delete•ˆ˜— –‰•ง€๋Š”๋ฐ ผ๋ฐ˜ œผ๋กœ ด๋ ‡ฒŒ „ –ธ๋˜–ด žˆ๋‹ค.
~cpp 
    void operator delete(void * memoryToBeDeallocated);
ธ๋Ÿฌ๋ฏ€๋กœ
~cpp 
    delete ps;
๋Š” ด๋Ÿฐ ฝ”๋“œฐ€ ˆ˜–‰๋œ‹  ๋ณด๋ฉด ๋œ‹ค.
~cpp 
    ps->~string();
    operator delete(ps);
(ž‘„ž ฃผ: ฑธ๋กœ new™€ delete˜ ™˜ƒ,‹ ๋น„„นจกŒ๋‹ค. )

ธ๋ฆฌ  ฒƒ˜ ˜๋ฏธ๋Š” ๋‹‹ ดˆธฐ™” ๋˜ง€ •Š€ raw๋กœ˜ ‚ฌšฉ˜ ฒฝšฐ—๋Š” new™€ delete operator๋กœ ธ๋ƒฅ ๋„˜ฒจ••œ‹ค๋Š” ˜๋ฏธฐ€ ๋œ‹ค. ฆ‰ ฝ”๋“œ ๋Œ€‹ — ๋‹Œ˜ ˜ˆ๋ฅผ ๋ณผˆ˜ žˆ„ ฒƒด๋‹ค.
~cpp 
    void * buffer = operator new(50*iszeof(char));
    ...
    operator delete(buffer);
œ„˜ ฝ”๋“œ๋Š” C++ƒ—„œ malloc ณผ free ๋ฅผ ˜œ ฒƒณผ ๋™•œ —ญ• „ •œ‹ค.

ธ๋ ‡๋‹ค๋ฉด, ด๋ฒˆ— ๋‹‹ € placement new๋ฅผ ‚ฌšฉ•„œ ๋ฉ”๋ชจ๋ฆฌƒ— ฒด๋ฅผ ๋งŒ๋“ค—ˆ๋‹ค๋ฉด delete๋ฅผ ‚ฌšฉ• ˆ˜ —†„ บผ๋ผ๋Š” ˜ˆธก„ • ˆ˜ žˆ„ ฒƒด๋‹ค. ž ๋‹Œ ฝ”๋“œ๋ฅผ ๋ณด๋ฉด„œ ๋ช…‹œ ธ delete๋ฅผ –‰•˜๋Š” ฝ”๋“œ๋“ค„ ๋ณดž
~cpp 
    void * mallocShared(size_t size);
    void freeShared(void *memory);

    void *shareMemory = mallocShared(sizeof(Widget));
    Widget *pw = constructWidgetInBuffer(shareMemory, 10);  // placement newด๋‹!

    ...
    delete pw;  // ด๋ ‡ฒŒ •„œ๋Š” •ˆ๋œ‹ค. sharedMemory๋Š” mallocShared—„œ • ‹น๋˜๋Š”๋ฐ –ดฐŒ • ˆ˜ žˆœผ๋ฆฌš”.
                // ธ๋ ‡๋‹ค๋ฉด ๋‹Œณผ ฐ™€ ฝ”๋“œ๋กœ •••œ‹ค.

    pw->~Widget();  // ๋จผ € ž„˜๋กœ ŒŒดดž๋ฅผ ˜œ•œ‹ค. ด๋ ‡ฒŒ •˜๋ฉด pwณผ ด€๋ จ๋œ ž›„ ๋ฐ˜™˜• ฒƒ .
    freeShared(pw); // œข… œผ๋กœ pwฐ€ • ‹น๋œ ๋ฉ”๋ชจ๋ฆฌ ˜—ญ„ • œ ‹œ‚จ๋‹ค.

  • Arrays
๋ณ„‹ค๋ฅธ Šน๋ณ„•œ ง€ ‚ฌ•—†๋‹ค. —ฌƒœ นŒง€˜ —ฐžฅ„  ‹จ new๋ฅผ šฉ•œ ๋ฐฐ—ด • ‹„ ‚ญ œ•  ฒฝšฐ
~cpp 
    string *ps = new string[10];
    delete [] ps;
™€ ฐ™„ ๋งžถ”–ด ฃผ–ด••œ‹ค. placement๋Š” ๋‹œ„˜ ง€‹œ ‚ฌ•— ๋”ฐ๋ฅด๋Š” ฒƒ  operator delete๋Š” item 6—„œ™€ ฐ™ด for๋ฌธœผ๋กœ ˆœšŒ•˜๋ฉด„œ ง€›Œ ฃผ–ด••œ‹ค.

๋งˆง€๋ง‰œผ๋กœ —ฌธฐ„œ ๋ณด๋‹‹œ”ผ new™€ delete๋ฅผ ๋งŒ๋“œ๋Š” žฒด๋Š” ๋‹‹ กฐ • • ˆ˜ —†๋Š” ˜—ญ— กดžฌ•˜ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ • ‹€ ๋‹‹ ˜ †•„๋ž˜ žˆ๋‹ค. new™€ delete๋ฅผ œ ™”๋‚˜ ˆ˜ • • •Œ ผญ ธฐ–ต•ด๋ผ ๋‹‹  •๋ง๋กœ ฑธ • ˆ˜ —†๋Š”ฐ€— ด€•„œ ๋งด๋‹ค. ๋‹‹ € ฒƒ๋“ค˜ ๋ฐฉ๋ฒ•(new,delete๋ฉ”๋ชจ๋ฆฌ • ‹น ๋ฐฉ๋ฒ•)€ ๋ณ€ฒฝ• ˆ˜ žˆ๋‹ค. ธ๋Ÿฌ๋‚˜ ธ๋“ค€ –ธ–ด— ˜•„œ œ •๋˜–ด  žˆ๋Š” ˜—ญด๋‹ค.


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