C++ casts
https://jun-13.tistory.com/146
[C++] casts
C++ casts c++์๋ ๋ค์ํ ํ ๋ณํ ์ฐ์ฐ์(๋๋ ์บ์คํธ ์ฐ์ฐ์)๊ฐ ์๋ค. static_cast reinterpret_cast dynamic_cast const_cast ์์ ๊ฐ์ด ํฌ๊ฒ 4๊ฐ์ง์ cast๋ค์ด ์กด์ฌํ๋ค. static_cast ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ํ ๋ณํ ์ฐ์ฐ์๋ก,
moaoh.dev
Exercise 00: Conversion of scalar
static_cast<T>
ํ์ ๊ฐ์ ํ ๋ณํ์ ์ํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ํ ๋ณํ ์ฐ์ฐ์์ด๋ค.
int i = 42;
double d = static_cast<double>(i); // int๋ฅผ double๋ก ๋ณํ
double d = 3.14;
int i = static_cast<int>(d); // double์ int๋ก ๋ณํ (์ ์ ๋ถ๋ถ๋ง ๋จ์)
์์ ๊ฐ์ ํ์๊ณผ ๊ฐ์ด ๋ ํฐ ํ์์ด๋ ๋ ์์ ํ์์ ์๊ด์์ด ํ๋ณํ์ด ๊ฐ๋ฅํ๊ณ
int i = 10;
char c = static_cast<char>(i); // int๋ฅผ char๋ก ๋ณํ
์์ ๊ฐ์ด ์๋ก ๊ด๋ จ์ด ์๋ ๋ฐ์ดํฐ ํ์๊ฐ์๋ ํ๋ณํ์ด ๊ฐ๋ฅํ๋ค.
(c++) static class
ํด๋น๊ณผ์ ์์๋ ScalarConverter๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ค๋ผ๊ณ ํ๋๋ฐ ํด๋น ํด๋์ค๋ **static class**ํํ๋ก ๋์ด์์ด์ผํ๋ค๊ณ ํ๋ค. ๊ทธ๋์ ๊ทธ๊ฒ์ ๋ํ ์๋ฏธ๋ฅผ ์ฐพ์๋ณด๋ ๋ค๋ฅธ ๋ถ๋ค์ ์ ์ ๋ฉค๋ฒ๋ง ๊ฐ์ง๊ณ ์๋ ํด๋์ค๋ฅผ static class๋ผ๊ณ ํ๋ค๊ณ ํ๋ค.
๊ทธ๋์ ์ ์ ๋ฉค๋ฒ๋ง ๊ฐ์ง๊ณ ์๋ ํด๋์ค๊ฐ ๋ฌด์์ธ๊ฐ?
์ฑ๊ธํค(Singleton)
c++์์ ์ ์ ๋ฉค๋ฒ๋ง ๊ฐ์ง๋ ํด๋์ค๋ฅผ ์ฑ๊ธํค(singleton)์ด๋ผ๊ณ ์ด์ผ๊ธฐํ๋ค๊ณ ํ๋ค.
- ์ ์ ๋ฉค๋ฒ๋์์ ๊ฐ์ด static void * ํ์์ผ๋ก ์ ์ธ๋ ํจ์๋ฅผ ์ ์ ๋ฉค๋ฒํ์์ผ๋ก ์ ์ธ์ด ๋์ด์๋ค๊ณ ์ด์ผ๊ธฐํ๋ค (static์ ์ ๋ฌด)์์ ์์ ์์ ์ ์ ๋ฉค๋ฒ๋ก ์ ์ธ๋๊ฒฝ์ฐ์ ๊ทธ๋ฅ ๋ฉค๋ฒ๋ก ์ ์ธ์ด ๋์ด์๋ ๊ฒฝ์ฐ๋ฅผ ๋น๊ตํ๊ณ ์๋๋ฐ ์ ์ ๋ฉค๋ฒ์ ๊ฒฝ์ฐ์๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๊ณ ๋ ๋ฉค๋ฒํจ์๋ฅผ ํด๋์ค ์ด๋ฆ์ ์ฌ์ฉํ์ฌ ํธ์ถ์ด ๊ฐ๋ฅํ๋ค.
- class MyClass { public: void memberFunction() { std::cout << "This is a member function." << std::endl; } static void staticFunction() { std::cout << "This is a static member function." << std::endl; } }; int main() { MyClass myObject; myObject.memberFunction(); // ๋ฉค๋ฒ ํจ์๋ฅผ ํธ์ถํ๊ธฐ ์ํด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉ MyClass::staticFunction(); // ์ ์ ๋ฉค๋ฒ ํจ์๋ฅผ ํด๋์ค ์ด๋ฆ์ ์ฌ์ฉํ์ฌ ํธ์ถ }
- class MyClass { public: static void staticFunction() { std::cout << "This is a static member function." << std::endl; } }; int main() { MyClass::staticFunction(); // ์ ์ ๋ฉค๋ฒ ํจ์ ํธ์ถ return 0; }
class Singleton {
public:
// ์ ์ ๋ฉค๋ฒ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๊ธํค ์ธ์คํด์ค์ ์ ๊ทผ
static Singleton& getInstance() {
// ์ธ์คํด์ค๊ฐ ์ด๋ฏธ ์กด์ฌํ๋์ง ํ์ธํ๊ณ , ์์ผ๋ฉด ์์ฑ
if (!instance) {
instance = new Singleton;
}
return *instance;
}
// ๋ค๋ฅธ ๋ฉค๋ฒ ํจ์์ ๋ฐ์ดํฐ ๋ฉค๋ฒ๋ค์ ์ ์
void doSomething() {
// ์ฑ๊ธํค ํด๋์ค์ ๋์
}
private:
// ์์ฑ์์ ์๋ฉธ์๋ฅผ private๋ก ์ ์ธํ์ฌ ์ธ๋ถ์์ ๊ฐ์ฒด ์์ฑ์ ๋ง์
Singleton() {}
~Singleton() {}
// ์ ์ ๋ฉค๋ฒ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ผํ ์ธ์คํด์ค ๊ด๋ฆฌ
static Singleton* instance;
};
// ์ ์ ๋ฉค๋ฒ ๋ณ์ ์ด๊ธฐํ
Singleton* Singleton::instance = nullptr;
int main() {
Singleton& singleton = Singleton::getInstance(); // ์ฑ๊ธํค ์ธ์คํด์ค ๊ฐ์ ธ์ค๊ธฐ
singleton.doSomething();
return 0;
}
try - catch
try {
...
}
catch(...) {
throw ImpossibleException();
}
try - catch๋ฌธ๋ฒ์์๋ catch์์ญ์์ ๋ ๋ค์ throw๋ฅผ ๋์ง ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
๊ทธ๋์ ์์ ๊ฐ์ด throw๋ฅผ ์ก์ ์์ญ์์ ๋ค์ throw๋ฅผ ๋์ง๋๊ฒ ๋ง๋ ์ฝ๋์ธ๊ฐ? ๊ณ ๋ฏผ์ ํด๋ณด๊ณ ์์๋ดค์๋์ ์ผ๋ฐ์ ์ผ๋ก๋ ์์ข์ ํ์์ผ๋ก ๊ฐ์ฃผ๋๋ค๊ณ ํ๋ค. ( ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ณต์กํด์ง๊ณ ์์ธ ์ฒ๋ฆฌ๊ฐ ์ ๋๋ก ์์ด๋ฃจ์ด์ง ์ ์๋ค๋ผ๊ณ ํ๋ค. )
double doubleValue = std::stod(strValue);
๊ทธ๋ ์ง๋ง ์์ ๊ฐ์ด std::stod() ํจ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์คํจํ ๊ฒฝ์ฐ ์ปดํ์ผ์ชฝ์์ ๋ง์์ฃผ๋ ๊ฒ์ด ์๋๋ผ stod ํจ์์์ std::invalid_argument ํ์์ผ๋ก throw๋ฅผ ๋์ง๋ค๊ณ ํ๋ค.
์์ ๊ฐ์ ๊ฒฝ์ฐ์ subject์์๋ stod์์ ๋ฐํ๋๋ ๊ฐ์ด ์๋๋ผ subject์์ ์๊ตฌํ๋ exception๊ฐ์ผ๋ก ๋ฐํ์ ํด์ผํ๋
try {
double doubleValue = std::stod(strValue);
}
catch(...) {
throw ImpossibleException();
}
์์ ๊ฐ์ ํ์์ผ๋ก stod๊ฐ ์คํจํ๊ฒฝ์ฐ catch์์ ํด๋น ์ค๋ฅ๋ฅผ ์ก์ ์ฌ์ฉ์๊ฐ ์ํ๋ ๊ฐ์ผ๋ก ์ ํํ๋ ๋ฐฉ์์ ์ฌ์ฉํ์๋ค.
stod
์ฒ์์๋ **stod stoi stof**๋ค์ ์ฌ์ฉํด์ ๊ตฌํ์ ํ์์ผ๋, ํด๋น ํจ์๋ค์ c++11์ธ๊ฑธ๋ก ํ์ธ์ด ๋์ด
**strtod**ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ
isnan, isinf
std::isnan (Is Not a Number): ์ด ํจ์๋ ์ฃผ์ด์ง ์ซ์๊ฐ NaN (Not-a-Number)์ธ์ง ์ฌ๋ถ๋ฅผ ํ์ธ
std::isinf (Is Infinite): ์ด ํจ์๋ ์ฃผ์ด์ง ์ซ์๊ฐ ๋ฌดํ๋ (positive ๋ฌดํ๋ ๋๋ negative ๋ฌดํ๋)์ธ์ง ์ฌ๋ถ๋ฅผ ํ์ธ
Exercise 01: Serialization
reinterpret_cast<T>
์ฃผ๋ก ์ฃผ์๋ ํฌ์ธํฐ ๋ฑ์ ๋ค๋ฅธ ํ์์ผ๋ก ๋ณํํ ๋ ์ฌ์ฉ๋๋ค.
#include <iostream>
int main() {
int x = 42;
double* y = reinterpret_cast<double*>(&x); // int ์ฃผ์๋ฅผ double ํฌ์ธํฐ๋ก ๋ณํ
int z = x;
std::cout << "z : " << z;
return (0);
}
// output
// z : 42
uintptr_t
์ ์ํ ๋ฐ์ดํฐ ํ์ ์ค ํ๋๋ก, ์ฃผ์๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ๊ฒ์ผ๋ก ์ฌ์ฉ๋๋ค.
Exercise 02: Identify real type
dynamic_cast
์ฃผ๋ก ์์ ๊ด๊ณ๊ฐ ์๋ ํด๋์ค์์ ์ฌ์ฉ๋๋ฉฐ, ์ฃผ๋ก ๋คํ์ฑ(polymorphism)๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ cast
class Base {
public:
virtual void someFunctionInBase() {
std::cout << "Base class function" << std::endl;
}
};
class Derived : public Base {
public:
void someFunctionInDerived() {
std::cout << "Derived class function" << std::endl;
}
};
Base* basePtr = new Derived;
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
// ์ฑ๊ณต์ ์ผ๋ก ํ ๋ณํ
}
๋ถ๋ชจ๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๋ฅผ ์์์ ๊ฐ๋ฆฌํค๋๋ก ๋ฐ๊พธ๋ ๋ค์ด ์บ์คํ ์ ์ฌ์ฉ๋๋ ์บ์คํ ์ dynamic_cast๋ผ๊ณ ํ๋ค.
try {
A& a = dynamic_cast<A&>(aRef); // ๋ค์ด์บ์คํธ ์๋
// ๋ค์ด์บ์คํธ ์ฑ๊ณต
std::cout << "Downcast successful." << std::endl;
} catch (const std::bad_cast& e) {
// ๋ค์ด์บ์คํธ ์คํจ
std::cerr << "Downcast failed: " << e.what() << std::endl;
// ์คํจํ ๊ฒฝ์ฐ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ถ๊ฐํ ์ ์์
}
A &a = dynamic_cast<A&>(p); ๋ฅผ ์คํจํ์ ๊ฒฝ์ฐ std::bad_cast ์์ธ๋ฅผ ๋์ง๋ค.
ํด๋น ๊ฒฝ์ฐ์ if-else dynamic_cast๊ฐ ์คํจํ ๋ ๋ฐํ๋๋ ๊ฐ์ด nullptr๊ฐ ์๋ ์ฐธ์กฐ ์์ฒด๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ฐธ์กฐ์ ๋ํ dynamic_cast ์คํจ๋ try-catch๋ฅผ ํตํด์ ์ก์๋ผ ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ค๋ฅธ cast์ ๊ฒฝ์ฐ์๋ ๋ฐ๋ก try-catch์ ์์ธ์ฒ๋ฆฌ๋ ํ์์๋๊ฐ?
์ธ์๋ฅผ ํฌ์ธํฐ๋ก ๋ฐ๋๋ ๋ ํผ๋ฐ์ค๋ก ๋ฐ๋๋์ ๋ฐ๋ผ ๊ตฌํ ๋ฐฉ์์ด ๋ฐ๋๋๋ฐ, dynamic_cast๋ฅผ ์คํจํ์ ๋ ํฌ์ธํฐ์ผ ๊ฒฝ์ฐ NULL์ ๋ฐํํ์ง๋ง ๋ ํผ๋ฐ์ค์ ๊ฒฝ์ฐ(NULL์ ๋ชป์ฐ๋) exception์ด ์ผ์ด๋๋ค.
'42seoul > projects' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[CPP Module] 07 (0) | 2024.03.13 |
---|---|
[C++] templates (0) | 2024.03.13 |
[C++] casts (0) | 2024.03.13 |
[CPP Module] 05 (0) | 2024.03.13 |
[C++] Repetition and Exceptions (0) | 2024.03.13 |