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.0411 sec