ex00 My First Canonical Class
์๋๊ฐ ๋ญ๋ฐ?????? ์๋์์ ์ฌ๋๋ก ๋ง๋ค๊ฑฐ๊ณ , ์ฌ๊ธฐ๋ ๊ทธ๋ฅ ์ง์ง canonical class form์ผ๋ก ํด๋์ค๋ฅผ ์์ฑํด๋ณด๋ ๋ถ๋ถ. ์ผ๋จ ๋ณ ๊ธฐ๋ฅ ์๋๋ผ๋ ์ฌ๊ธฐ์๋ ๋ง๋ค๋ผ๊ณ ํ๋ ํผ ๋๋ก ํด๋์ค๋ฅผ ์์ฑํ๋ค.
Canonical์ด๋?
Canonical :์ ๊ท์ ์ธ. -> Canonical form class :์ ๊ท์ ์ธ ํํ์ ํด๋์คโฆ
Orthodox canonical class form = OCCF
์ฌ์ค OCCF์ ๋ํด ์คํผ์ ํ ๋ ํผ๋ฐ์ค๋ ์์ด๋ณด์ธ๋คโฆ ํ์ง๋ง ๊ด๋ก์ ์ผ๋ก ๋ค์๊ณผ ๋ด์ฉ์ด ๊ฐ์ฅ ์ค์ํด ๋ณธ์ธ๋ค.
OCCF๋ฅผ ์ค์ํ๋ ํด๋์ค๋ c++98, c++03์ปดํ์ผ๋ฌ๊ฐ ์๋์ ์ผ๋ก ์์ฑํ๋ ์๋์ ๊ฐ์ ํญ๋ชฉ๋ค์ ๋ํด์ ์ ์ธ ๋ฐ ์ ์ํ๋ค(=์ปดํ์ผ๋ฌ๊ฐ ์๋ ์์ฑ๋๋ ํญ๋ชฉ๋ค์ ๋ํด์ ํธ๋ค๋ง ํด๋๋๋ค).
- ๊ธฐ๋ณธ์์ฑ์ -> Class::Class()
- ๋ณต์ฌ ์์ฑ์(๋์ ์์ฑ์?) -> Class::Class(const Class&)
- ๋์ ์ฐ์ฐ์ -> Class& operator=(const Class&)
- ์๋ฉธ์ -> Class::~Class()
ref : advanced c++ programming styles and idioms, James O. Coplien ๋ฐ์ท ๊ธ, Orthodox canonical class form
ex01 Towards a more useful fixed point class
ex00์์ ๋ง๋ ํด๋์ค์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ธ๋งํ ๊ธฐ๋ฅ๋ค์ ์ถ๊ฐํ๋ ๋จ๊ณ
๊ณ ์ ์์์
๊ณผ์ ์์ ์๊ตฌํ๋ ๊ณ ์ ์์์ ์ ํํ๋ 32bit(float)์ค 24bit๋ ์ ์๋ฐ์ดํฐ, 8bit๋ ์์๋ฐ์ดํฐ์ด๋ค. ์ฆ, ์์๋ฅผ ํํํ๋ ํฌ๊ธฐ๊ฐ 8bit๋ก ๊ณ ์ ์ ์ธ ์๋ฃํ์ ์๊ตฌํ๋ค.
float๋ฐ์ดํฐ๋ฅผ 8bit๋งํผ shift(= *256)ํ์ฌ ์์๋ถ๋ถ 8bit๋ฅผ intํ์ผ๋ก ๋ณด์กดํ๋ค ํ์ํ ๋ floatํ์ผ๋ก ๋ณต๊ตฌํ๊ณ ์ ํ๋ค. ์๋ฅผ ๋๋๊ฒ ๊ฐ์ฅ ์ดํด๊ฐ ๋น ๋ฅด๋ค.
float floatFloat = 42.4199982;
float floatTemp;
int intTemp;
// 8bit๊ธธ์ด์ ์์๋ถ๋ง ๋ณด์กดํ์ฌ intํ์ผ๋ก ์ ์ฅ.
floatTemp = floatFloat * (1 << 8);
intTemp = (int)roundf(floatTemp);
// int๋ก ์ ์ฅ๋๊ฑธ ๋ณต๊ตฌํ์ฌ ์ฌ์ฉ.
std::cout << ((float)intTemp / (1 << 8)) << std::endl;
์์ ์ฝ๋๋ฅผ ์ค๋ช ํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๋ฐ์ค : ๋ณด์กดํ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ํ๋.
- ๋ง์ฝ
42.4199982f
๋ ์๋์ ๊ฐ์ bitํํ์ด๋ค. <pre>0(sign) 10000100(์ง์๋ถ) 01010011010111000010100(๊ฐ์๋ถ)</pre> 42.4199982f
์1 << 8
(256)์ ๊ณฑํ๋ฉด10859.5195f
์ด๋ฉฐ bitํํ๋ ์๋์ ๊ฐ๋ค. <pre>0(sign) 10001100(์ง์๋ถ) 01010011010111000010100(๊ฐ์๋ถ)</pre>- ๊ฐ์๋ถ๋ ๊ทธ๋๋ก์ง๋ง, ์ง์๋ถ๋ฅผ ํตํด ์ ์์ ๋ฒ์๊ฐ ๋ณํ๋ค
- 10์ง์๋ก ์๋ฅผ ๋ค๋ฉด
4.123
๋ฅผ41.23
์ผ๋ก ๋ฐ๊พผ๊ฑด๋ฐ, 2์ง๋ฒ ๊ด์ ์ด๋ผ์ ๋ณต์กํ๊ฒ ๋ณด์ธ๋ค. roundf()
๋ฅผ ํตํด10859.5195f
์ ์์์ ๋ถ๋ถ์ ๋ ๋ฆฐ๋ค. ์ด๋ ๋ณด์กดํ๊ณ ์ ํ๋ ๋ถ๋ถ ๋ฐ๊นฅ์ ๋ฐ์ดํฐ๋ ๋ ๋ฆฌ๋ ๊ฒ์ด๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ ๋ฐํ๋๋10860f
์ bit ๋ฐฐ์ด์ ์๋์ ๊ฐ๋ค. <pre>0(sign) 10001100(์ง์๋ถ) 01010011011000000000000(๊ฐ์๋ถ)</pre>- intํ์ผ๋ก ํ๋ณํํ์ฌ ์ ์ฅํด๋๋๋ค.
10860
์0010 0100 1101 1100
์ผ๋ก, ์๋ณธ float์๋ ์ฐ๊ด์ฑ์ด ์๋ค. ํ์ง๋ง ํ์ํ ๋ ๋ค์ float๋ก ๋ณํํ10860f
๋ ์๋์ ๊ฐ๋ค. <pre>0(sign) 10001100(์ง์๋ถ) 01010011011000000000000(๊ฐ์๋ถ)</pre> - ์ด๋ฅผ ๋ค์
1 << 8
๋ก ๋๋๋ฉด ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ก ๋ณต๊ตฌํ ์ ์๋ค. <pre>0(sign) 10000100(์ง์๋ถ) 01010011011000000000000(๊ฐ์๋ถ)</pre> - ์ฆ, intํ์ผ๋ก ๋์๋๋ ์ซ์๋ง ์ ์ฅํด๋๊ณ , ํ์ํ ๋ ํ๋ณํ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋ณต๊ตฌํ๋ค.
์ด๋ ๋ค์ด์์ ๋ณํํ ๋ฐ์ดํฐ๊ฐ int์ธ์ง float์ธ์ง๋ ์ ์ ์์ผ๋ฏ๋ก intํ์ ์ ๋ ฅ๋ฐ์๋๋ left shift์ฐ์ฐ์ ํ๊ณ , ์ถ๋ ฅํ ๋ ์ผ๊ด์ ์ผ๋ก right shift์ฐ์ฐ์ ํ์ฌ ๋ณด์กดํ๊ธฐ ์ํด ์ผ์ชฝ์ผ๋ก ์ด๋์์ผฐ๋ ์์์ 8bit๋ฅผ ๋ค์ ์ค๋ฅธ์ชฝ์ผ๋ก 8bit์ฎ๊ธด๋ค.
์์ฐํโฆ ๋ณธ๋ฌธ์์ ์ด๋ค๊ฑธ ์๊ตฌํ๋์ง ํ์ ํ๊ธฐ๋ ํ๋ ๋ฐ, ์ด๊ฑธ ์๊ฐํด๋ด๊ธฐ๋ ์ ๋ง ํ๋ค๊ฑฐ ๊ฐ๋ค. ์ด ๋ธ๋ก๊ทธ์์ ๊ณ ์ ์์์ ์ ์ด๋ป๊ฒ ๋ง๋ค์ง ๊ฐ๋ ์ ํ์ ํ๊ณ , IEEE 754 Converter์์ bit๊ฐ์ด ์ด๋ป๊ฒ ๋ณํ๋์ง ํ์ธํ๋ฉด์ ์๋ฒฝํ๊ฒ ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ๋ค.
์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ(ex01, ex02)
์์ ๋ฅผ ์ฑ ๋ณด๋ ex02์ ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ์ ์ง์ค์ ์ผ๋ก ํ๊ฒ ๋๋ฏ๋ก, ํ๋ฒ์ ์ ๋ฆฌ.
๊ณผ์ ์์ ์๊ตฌ : ๋์
์ฐ์ฐ์(=
), ์ฐ์ ์ฐ์ฐ์(+
, -
, *
, /
), ๋น๊ต์ฐ์ฐ์(>
, <
, >=
, <=
, ==
, !=
), ์ฆ๊ฐ ์ฐ์ฐ์(++Fix
, --Fix
, Fix++
, Fix--
), stream ์ฝ์
์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ(<<
)
์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ ์ ์ธ ์์น
์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ์ ํด๋์ค ๋ด์์ ํ๊ฑฐ๋, ํด๋์ค ๋ฐ์์ ํ ์ ์๋ค. ์ด๋ ์๊ธฐ ์์ ์ ๋ฆฌํดํ๊ฑฐ๋ private์์ญ์ ๋ฉค๋ฒ๋ฅผ ์ฌ์ฉํด์ผ ์ฐ์ฐ์๋ค์ ๋ด๋ถ ์ฐ์ฐ์๋ก ์ค๋ฒ๋ก๋ฉ ํ๋ค.
=
,()
,[]
,->
๋ ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ์ ํด๋์ค ๋ด๋ถ์์๋ง ๊ฐ๋ฅํ๋ค.- ์ค๋ฒ๋ก๋ฉ๋ ์ฐ์ฐ์@๋ a.operator@(b), operator@(a, b)ํํ ์ฒ๋ผ ํธ์ถํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
์ญ ์ฐพ์๋ณธ ๊ฒฐ๊ณผ ํน์ ๋ช๊ฐ๋ฅผ ์ ์ธํ๊ณ ๋ ์ด๋์ ๋ฉค๋ฒ๋ก ์ ์ธ ํ ์ง ๋ง์ง๋ ํฌ๊ฒ ์๊ด ์๋๊ฒ ๊ฐ๋ค. ํ์ง๋ง ๊ฐ์ฒด์งํฅ์ ์ธ ๊ด์ ์์ ๋ณผ๋ ์ ์ญ์ ์ง์ํ๋๊ฒ ์ข๋ค. ๋ฐ๋ผ์ ํด๋น ๊ณผ์ ์์๋ ํฐ ์ด์ ๊ฐ ์์ผ๋ฉด ๋ฉค๋ฒ๋ก์ ์ค๋ฒ๋ก๋ฉํ๋ค.
์ค๋ฒ๋ก๋ฉ ์ ํ์ฌํญ
::
(๋ฒ์์ฐ์ฐ์),.
(๋ฉค๋ฒ ์ ๊ทผ),.*
(ํฌ์ธํฐ๋ฅผ ํตํ ๋งด๋ฒ ์ ๊ทผ),?
(์ผํญ์กฐ๊ฑด์ฐ์ฐ์)๋ ์ค๋ฒ๋ก๋ฉ ๋ถ๊ฐ- ๊ธฐ์กด์ ์๋ ์๋ก์ด ์ฐ์ฐ์๋ ์์ฑ ๋ถ๊ฐ
->
๋ฅผ ์ค๋ฒ๋ก๋ฉ ํ ๋๋ rawํฌ์ธํฐ(?)๋ ->๊ฐ ์ฐจ๋ก๋ก ์ค๋ฒ๋ก๋ ๋๋ ๊ฐ์ฒด๊ฐ ๋ฐํ๋์ด์ผํ๋ค.||
,&&
๋ฅผ ์ค๋ฒ๋ก๋ ํ๋๊ฒ์ ์ด๋ค์ short-circuit evaluation์ ์์ด๋ฒ๋ฆฌ๊ฒ ๋๋ค.- short-circuit evaluation :
A && B
์์A
๊ฐFalse
๋ฉดB
๋ฅผ ํ์ธํ์ง ์๊ณ ๋ฐ๋ก ๋์ด๊ฐ๋ ๊ธฐ๋ฅ. - C++17๊น์ง๋ short-circuit evaluation๋ฅผ ์๋๊ฒ์
,
๋ ํฌํจ๋๋ค๊ณ ํ๋ค.
- short-circuit evaluation :
๋์
์ฐ์ฐ์ ์ค๋ฒ๋ก(=
, ์ปดํ์ผ๋ฌ ์๋ ์์ฑ)
Fix& operator=(Fix& other);
-> ์์๋ณต์ฌ ๊น์๋ณต์ฌ์ ์ฃผ์.
๋ณต์ฌ ์์ฑ์(Fix(Fix& other))์ ํ์ฉ ๊ฐ๋ฅํ๋ฉฐ, ๋ณต์ฌ์์ฑ์ ๋ํ ์ปดํ์ผ๋ฌ๊ฐ ์์ผ๋ฉด ์๋์์ฑํ๋ค.
์ฐ์ ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ(+
, -
, *
, /
)
Fix operator+(Fix& term); // a + b โ a.operator+(b)
Fix operator-(Fix& term); // a - b โ a.operator-(b)
Fix operator*(Fix& term); // a * b โ a.operator*(b)
Fix operator/(Fix& term); // a / b โ a.operator/(b)
๋น๊ต์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ(>
, <
, >=
, <=
, ==
, !=
)
bool operator>(Fix& term); // a > b โ a.operator>(b)
bool operator<(Fix& term); // a < b โ a.operator<(b)
bool operator>=(Fix& term); // a >= b โ a.operator>=(b)
bool operator<=(Fix& term); // a <= b โ a.operator<=(b)
bool operator==(Fix& term); // a == b โ a.operator==(b)
bool operator!=(Fix& term); // a != b โ a.operator!=(b)
์ฆ๊ฐ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ(++Fix
, --Fix
, Fix++
, Fix--
)
์ฆ๊ฐ์ฐ์ฐ์๋ ๋งค๊ฐ๋ณ์ int ์ฌ๋ถ์ ๋ฐ๋ผ ์ ์์ฆ๊ฐ๊ณผ ํ์์ฆ๊ฐ์ ๊ตฌ๋ถํ๋ค. ์์ผ๋ฉด ํ์์ด๋ฉฐ ๋จ์ง ๋จ์์ ์ ์์ ํ์๋ฅผ ๊ตฌ๋ถํ๋ ์ฉ๋์ด๋ค.
๋ํ ์ ์์ ๊ฒฝ์ฐ ์ฆ๊ฐ์ด ๋ฐ์๋ ํ์ฌ์ ์์ (Fix&
)์ ๋ฆฌํดํ๊ณ , ํ์๋ ๋ฐ์๋๊ธฐ ์ด์ ์ ๊ฐ์ฒด(Fix
)๋ฅผ ๋ฏธ๋ฆฌ ๋ณต์ฌํ๊ณ ๋ฆฌํดํ๋ค.
Fix& operator++(); // ++fix
Fix& operator--(); // --fix
Fix operator++(int); // fix++
Fix operator--(int); // fix--
์ถ๊ฐ : ๋ณดํต์ ํ์ ์ฆ๊ฐ์ฐ์ฐ์ ๊ฒฝ์ฐ ํ์์ฐ์ฐ๋ณด๋ค ๋๋ฆฌ๋ค. ์ฆ๊ฐ ์ด์ ์ ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ๋ณต์ฌํด์ผํ๊ณ ์ด๋ฅผ ํฌ์ธํฐ/์ฐธ๊ณ ๊ฐ ์๋๋ผ ๊ทธ๋๋ก ๋ฐํํ๊ธฐ ๋๋ฌธ์ด๋ค.
stream ์ฝ์
/์ถ์ถ ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ(<<
, >>
)
- ํด๋น ์ฐ์ฐ์๋ค์ ์ค๋ฅธ์ชฝ ์ธ์๋ก ์ฌ์ฉ์๊ฐ ์ ์ํ ํ์ ์ ๋ฐ์ผ๋ฏ๋ก, ์ ์ญ์ผ๋ก ์ ์ธํ๋ค.
std::cout << fix
๊ฐ ๋ฉค๋ฒํจ์๋ก ์ ์ธ๋๋ค๋ฉด,std::cout.operator<<(fix)
๋กstd::cout
์ดoperator<<
๋ฅผ ํธ์ถํ๋ ํด๋์ค๊ฐ ๋ ๊ฒ์ด๋ค. ํ์ง๋ง iostream ๋ฐ ๊ธฐํ ์คํธ๋ฆผ๋ค์ C++ ํ์ค ํด๋์ค์ด๋ฏ๋ก ๋งด๋ฒ๋ก ์ค๋ฒ๋ผ์ด๋ฉ์ด ๋ถ๊ฐํ๋ค. ๋ฐ๋ผ์operator<<(std::cout, fix)
ํํ๋ก ์ ์ํ๊ธฐ ์ํด ์ ์ญ์ผ๋ก ์ ์ธํ๋ค.ostream& operator<<(std::ostream& os, Fix& term); //std::out << fix โ operator(std::out, fix)
ref : cppreference.com, ansohxxn ๋ธ๋ก๊ทธ
Fixed operator*(Fixed& other)
vs Fixed operator*(const Fixed& other)
const์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์๋ฌ ๋ฐ์.
main.cpp:6:33: error: invalid operands to binary expression ('Fixed' and 'Fixed')
Fixed const b( Fixed( 5.05f ) * Fixed( 2 ) );
~~~~~~~~~~~~~~ ^ ~~~~~~~~~~
./Fixed.hpp:35:8: note: candidate function not viable: expects an l-value for 1st argument
Fixed operator*(Fixed& other);
^
1 error generated.
์์ ์๋ฌ๋ด์ฉ์์ Fixed( 5.05f )์ Fixed( 2 )๋ ๊ฐ๊ฐ ์์๊ฐ์ฒด(l-value)๊ฐ ์์ฑํ๋ค. ์ด๋ C++์์ non-const๋ฉค๋ฒ๋ ์์๊ฐ์ฒด๊ฐ์ l-value์ ๋ฐ์ธ๋ฉ(์ฐธ์กฐ)ํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. -> lvaue๋ ์์ ๋ถ๊ฐ๋ฅํ ์์์ ์ธ ๊ฐ๋ค์ธ๋ฐ, const๊ฐ ์๋ ์ฐธ์กฐ๋ฅผ ํ๊ฒ ๋๋ฉด ์์ ์ ํ๊ฒ ๋๋ฏ๋กโฆ
ref : stack overflow, reference binding