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++์์๋ ํฌ๊ฒ ๋๊ฐ์ง ๋ฐฉ์์ ํจ์๋ก ํ๋ณํ์ ์ปดํ์ผ๋ฌ์๊ฒ ์ํ ์ํคํจ๋ค:
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
~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 ๋ฅผ ์ด๊ฒ์ฒ๋ผ ํด๋ณด์
๋ง์ฝ ๋น์ ์ ์ปดํ์ผ๋ฌ๊ฐ ์์ฒญ ๋ก์ ๊ฑฐ๊ฑฐ๋ ์ ์์๊ฐ ๊น๋นกํด์, ํน์ 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 &&, ||๋ ์ด๋ ๊ฒ ๋๊ฐ์ง์ ๊ฒฝ์ฐ๋ก ๋๋ฆด์ ์๋ค.
์ผ๋จ 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)์ ์ฌ์ฉ๋๋ค. ์๋๋ฅผ ๋ณด์
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_castoverlod ํ ์ ์๋ 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๊ฐ ์ฐ์์ ๋ฐ๋ฅธ ์๋ฏธ๋ค์ ์ฐจ์ด๋ฅผ ์ดํดํ๋ผ.
~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
๊ทธ๋ ์ง๋ง ์ฌ๋ฌ๋ถ์ด raw memory๋ก ๊ฐ์ฒด๋ฅผ ํ ๋นํ๋ค๋ฉด ์ด๊ธฐํ ๋ฃจํด์ด ํ์ํ๋ค.
(์ฌ๋ด-ํํ ๋๋ ์๋จ์ operator new๋ฅผ ๋ณด๋ ์๊ฐ ์ด ์๊ฐํ๋ค.)
๋ฐ๋ก operator new์ ํนํ ๋ฒ์ ์ธ placement new๋ก ํ ์ ์๋ค.
(์ฌ๋ด-ํํ ๋๋ ์๋จ์ 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 ๊ฒฐ๋ก !
the new operator : heap ๋ฉ๋ชจ๋ฆฌ ํ๋ณด์ ์์ฑ์ ํธ์ถ ๋์์
operator new : ํด๋น ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ํ๋ณด๋ง
placement new : ์ด๋ฏธ ํ๋ณด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์กด์ฌํ๊ณ ๊ฐ์ฒด ์ด๊ธฐํ๋ฅผ ์ํ๋ค๋ฉด
์ด๋ค ์ด์คํ๊ฒ ์ ๋ฆฌํ๊ณ ์ฐจํ ์ถ๊ฐ ํ ๊ฒ์ด๋ค.
- Deletion and Memory Deallocation
~cpp string *ps; ... delete ps; // delete operator ๋ฅผ ์ฌ์ฉํ๋ค.๋น์ ์ด ์ฐ๊ณ ์๋ ์ปดํ์ผ๋ฌ๋ ๊ฐ์ฒด ps point๋ฅผ ํ๊ดดํ๊ณ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ๋ค.
๋ฉ๋ชจ๋ฆฌ ํด์ (deallocaion)์ operator deleteํจ์์ ํํด์ง๋๋ฐ ์ผ๋ฐ์ ์ผ๋ก ์ด๋ ๊ฒ ์ ์ธ๋์ด ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ์๋ฏธ๋ ๋น์ ์ด ์ด๊ธฐํ ๋์ง ์์ raw๋ก์ ์ฌ์ฉ์ ๊ฒฝ์ฐ์๋ new์ delete operator๋ก ๊ทธ๋ฅ ๋๊ฒจ์ผ ํ๋ค๋ ์๋ฏธ๊ฐ ๋๋ค. ์ฆ ์ด์ฝ๋ ๋์ ์ ๋ค์์ ์๋ฅผ ๋ณผ์ ์์ ๊ฒ์ด๋ค.
~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
~cpp string *ps = new string[10]; delete [] ps;์ ๊ฐ์ด ์ง์ ๋ง์ถ์ด ์ฃผ์ด์ผ ํ๋ค. placement๋ ๋น๊ทผ ์์ ์ง์ ์ฌํญ์ ๋ฐ๋ฅด๋ ๊ฒ์ด๊ณ operator delete๋ item 6์์์ ๊ฐ์ด for๋ฌธ์ผ๋ก ์ํํ๋ฉด์ ์ง์ ์ฃผ์ด์ผ ํ๋ค.
๋ง์ง๋ง์ผ๋ก ์ฌ๊ธฐ์ ๋ณด๋ค ์ํผ new์ delete๋ฅผ ๋ง๋๋ ์์ฒด๋ ๋น์ ์ด ์กฐ์ ํ ์ ์๋ ์์ญ์ ์กด์ฌํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ๋น์ ์ ์์๋ ์๋ค. new์ delete๋ฅผ ์ต์ ํ๋ ์์ ํ ๋ ๊ผญ ๊ธฐ์ตํด๋ผ ๋น์ ์ด ์ ๋ง๋ก ๊ทธ๊ฑธ ํ ์ ์๋๊ฐ์ ๊ดํด์ ๋ง์ด๋ค. ๋น์ ์ ๊ทธ๊ฒ๋ค์ ๋ฐฉ๋ฒ(new,delete๋ฉ๋ชจ๋ฆฌ ํ ๋น ๋ฐฉ๋ฒ)์ ๋ณ๊ฒฝํ ์ ์๋ค. ๊ทธ๋ฌ๋ ๊ทธ๋ค์ ์ธ์ด์ ์ํด์ ๊ท์ ๋์ด ์ ธ ์๋ ์์ญ์ด๋ค.